Programmierkurs I (HTML, Java) Wintersemester 2004/05 Programmierkurs I (HTML, CSS, Java) - 1 Programmierkurs I 1. Programmierkurs I 1.1. (HTML, Java) Wintersemester 2004/05 Dr. Heinz Kredel Rechenzentrum Universität Mannheim • 2 Stunden Vorlesung und 2 Stunden Übungen • Zwischenfragen sind willkommen URL • http://krum.rz.uni-mannheim.de/pk1/ © Universität Mannheim, Rechenzentrum, 1998 - 2004. Last modified: Sun Oct 24 13:57:24 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 2 Programmierkurs I Inhaltsverzeichnis 1. Programmierkurs I 2. Hypertext Markup Language (HTML) 3. Extensible Hypertext Markup Language (XHTML) 4. Cascading Style Sheets (CSS) 5. Cascading Style Sheets 2 (CSS2) 6. Java, Einleitung 7. Java, Sprache 8. Java, Klassen 9. Java, Vererbung 10. Java, Packages 11. Java, Ströme 12. Java, Utilities 13. Java, Generik 14. Java Tools 15. Extensible Markup Language (XML) 16. Java API for XML Processing (JAXP) 17. Literatur Programmierkurs I (HTML, CSS, Java) - 3 Einleitung 2. Einleitung Abgrenzung zur Vorlesung Praktische Informatik (PI) PI1: Konzepte und Methoden der Informatik PI1: Beispiele mit verschiedenen Programmiersprachen: Scheme, Java, C/C++ PK1/2: Erlernen von Programmiersprachen PK1/2: Beispiele aus der Informatik, Wirtschaftsinformatik und anderen Bereichen PK1: die Programmiersprache Java PK2: die Programmiersprachen C und Assembler 2.1. Warum Programmieren? • Handwerk / Grundfertigkeit in der Informatik • wichtig für das Verständnis von Design und Konzepten • nicht nur 'rum klicken', sondern erschaffen der Anwendungen • wichtig ist das 'learning by doing' • weil es Spass macht 2.2. Lernziele • Einführung in die Programmierung mit Java. Kennenlernen von HTML und Java. Verstehen und Anwenden von HTML und Java. • Übungen mit ausgewählter Software 2.3. Inhalt • Einführung in die Entwicklung von Web-Seiten • HTML, XHTML, CSS • Einführung in die Programmierung mit Java • Sprachkonstrukte, Klassen, Vererbung, Packages, Ströme und Dateien, nützliche Hilfsklassen (Utilities), Generische Datentypen 2.4. Organisatorisches • Montags 2 Stunden Vorlesung • bei Bedarf Montags 2 Stunden Übungen bei Dirk Stegemann • in der Woche 2 Stunden Übungen bei zwei Tutoren Programmierkurs I (HTML, CSS, Java) - 4 Einleitung • ein Übungsblatt mit Aufgaben pro Woche • am Ende des Semesters müssen Sie eine Klausur schreiben und bestehen • es gibt Web-Seiten zur Vorlesung und zur Übung • Literatur • heute im Anschluss Einführung in den Übungsbetrieb und die Benutzung des PC-Pools © Universität Mannheim, Rechenzentrum, 2004. Last modified: Sun Oct 17 14:22:56 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 5 Hypertext Markup Language (HTML) 3. Hypertext Markup Language (HTML) • Einordnung • Elementares HTML • Volles HTML • Ausblick Programmierkurs I (HTML, CSS, Java) - 6 Hypertext Markup Language (HTML) 3.1. Einordnung • Standard Generalized Markup Language (SGML) • Extended Markup Language (XML) • WYSIWYG im Gegensatz zu Markup • Orientierung am Bildschirm • Problem: Drucken Entwicklung • erster Ansatz von Tim Berners-Lee, 1989 • erster Browser, und Server 1990/91 • HTML 1.0, erster Entwurf 1992 • Web-Technologie Public Domain, 1993 • HTML 2.0, 1995, November • HTML 3.2, 1997 Januar • HTML 4.0, 1997 Dezember • HTML 4.01, 1999 Dezember • XHTML 1.0, 2000 Januar • XHTML Basic, 2000 Dezember • XHTML 1.1 - Module based XHTML, 2001 Mai • XHTML 2.0, Working Draft, 2003 Januar Web-Zutaten 1. Identifikation von Objekten: URL, URI 2. Übertragung von Objekten: Protokolle, z.B. HTTP 3. Hypertext: Darstellung und Navigation, z.B. HTML HTML-Konzeption 1. Dokumentstruktur durch Markup 2. Dokument-Darstellung, Präsentation durch Browser 3. Interaktion 3.2. Elementares HTML HTML 4.0 ist eine SGML Anwendung Festlegung in der Document Type Definition (DTD) Programmierkurs I (HTML, CSS, Java) - 7 Hypertext Markup Language (HTML) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd" > Syntax • Zeichensatz: ISO/IEC 10646, Universal Character Set (UCS), Unicode 2.0 • Elemente: <name> Inhalt </name> • Markup oder Textauszeichnungen: Tags werden in spitze Klammern eingeschloßen: <tag> • bei einigen Elementen ist das Ende-Tag optional manchmal auch das Start-Tag, z.B. BODY • einige Elemente sind ohne Inhalt, d.h. leer • für XML auch kombinierte Beginn-Ende-Tags: <tag/> • Attribute: attname="wert" <tag att1="wert1" att2="wert2" > • Groß-Klein-Schreibung wird ignoriert • Kommentare: <!-- ignorierter Text --> • spezielle Zeichen: &lt; (<) &gt; (>) &auml; (ä) &amp; (&) &#229; (å) Dokumentstruktur • Grammatik von HTML • Schachtelung der Elemente • Festlegung in der Content-Model Spezifikation • Beispiel in EBNF: HTML = HEAD BODY UL = (LI)+ • in SGML: <!ELEMENT HTML O O (HEAD BODY) > <!ELEMENT UL - - (LI)+ > <!ELEMENT IMG - O EMPTY > • in XML: <!ELEMENT html (head body) > <!ELEMENT ul (li)+ > <!ELEMENT img EMPTY > Darstellung • durch Browser • Mosaic (April 1993), Netscape, MS Internet Explorer, W3C Amaya, Lynx, html2ps, Mobil-Telefone, Palm-Tops, Sprachausgabe, Blindenschrift • unbekannte Elemente werden ignoriert nur der Inhaltsteil wird dargestellt • unbekannte Attribute werden ignoriert • bei unbekannten Attribut-Werten wird der Default genommen Uniform Resource Locator (URL) • dienst://hostname/pfad/object.ext Programmierkurs I (HTML, CSS, Java) - 8 Hypertext Markup Language (HTML) • Dienst-Selektor • Hostname • Pfad-Selektor • Objekt im Dokument: doc.html#part_2 • Relative URIs: ../images/bild.gif oder adoc.html Elemente Element Bedeutung Content-Model html SGML Anwendung head body head Kopfinformationen title (script | style | meta | link)+ body eigentlicher HTML Teil alles ohne Kopfelemente title Titel, Inhaltsbezeichnung Text h1, ..., h6 Überschriften Text a Verweis, Link, Anker Linktext etc. p Paragraph alles ohne Block-Elemente ul, ol Listen: unnumeriert, numeriert li+ dl Definitionslisten (dt|dd)+ li, dt, dd Listenelement, Definitionsterm, Definition alles mit Ausnahmen img Bild im Text empty pre vorformatierter Text Text br Zeilenumbruch EMPTY em, strong, code Betonung, Hervorhebung, Auszeichnung Text blockquote, q Einrückung Text unvollständige Auswahl Blanks und Zeilenumbrüche im Dokument werden (mit Ausnahmen) ignoriert Attribute Attribut Bedeutung Werte href Link URI in a Text name Ziel von einem Link in a Text src Bild URI in img Text alt Alternative Bezeichnung in img Text align Textausrichtung in p (left | center | right) value Nummer in ol li Zahl type Nummerstil in ul li (disk | square | circle) title zusätzliche Beschreibung Text bgcolor Hintergrundfarbe black, silver, gray, white, maroon, red, purple, fuchsia, green, lime, olive, Programmierkurs I (HTML, CSS, Java) - 9 Hypertext Markup Language (HTML) yellow, navy, blue, teal, aqua oder #rrggbb Beispiele 3.3. Volles HTML Erweiterungen • Formulare • Tabellen • Frames • Style Sheets, Darstellungsvorlagen • Scripte, Eingebettete Programme • Eingebettete Objekte, Applets • Internationalization, I18N Unicode, Textrichtung Elemente Element Bedeutung Content-Model form Formulare (input | select | other)+ input Eingabefeld im Formular EMPTY select Auswahl-Menue (optgroup | option)+ option Auswahl-Option Text der Option textarea Eingabebereich im Formular Anfangstext table 2-D Tabellen caption, tr+ tr Tabellen Zeile (th | td)+ th, td Tabellen Element alles mit Ausnahmen map Bilder mit Links verknüpfen area+ | other area Beschreibung der Bildkoordinaten EMPTY html SGML Anwendung head frameset frameset Aufteilung der Anzeigefläche frame+ | noframes frame separate Anzeigefläche EMPTY noframes alternative ohne Frames alles link Verweise, mit Rollenangaben, z.B. auf Style Sheet EMPTY style Stilangabe Stil-Script script JavaScript Programm im Text Programm Programmierkurs I (HTML, CSS, Java) - 10 Hypertext Markup Language (HTML) applet Java Programm wie Bild param+ param Parameter für Java Programm EMPTY object Programm oder Bild param+ meta Information über die Seite EMPTY div Dokument-Abschnitt, Block alles span Text-Abschnitt, Inline alles ohne Block-El. del, ins Text Revisionen alles mit Ausnahmen Attribute Attribut Bedeutung Werte action URL eines (CGI-)Programms in form Zeichenkette method HTTP Methode in form (get | post) type Typ eines Eingabefelds in input (text | password | radio | checkbox | submit | reset | file | hidden | image | button) selected, value Option mit Wert in option selected, Wert border Rahmentyp ( solid | none | dashed | n) height, width Grösse Pixel, Prozent, Meter cellpadding, cellspacing Abstand zwischen Text und Rand Abstand zwischen Zellen Pixel, Prozent, Meter usemap Verweis auf zugeordnete map in img Bezeichner shape Typ der area circle | rect | poly coords Koordinaten der area Liste rows, cols Spezifikation der Zeilen, Spalten in frameset Pixel, Prozent, Meter name Name in frame Bezeichner frameborder Rahmentyp eines Frames ( solid | none | dashed | n) target Zielframe zur Anzeige der Seite in a Bezeichner rel, rev z.B. Stilverweis in link stylesheet | next | prev style Stilinformation fast überall CSS Text class CSS-Klassen-Identifikator, fast überall Bezeichner id Identifikator wie name, fast überall Bezeichner language Programmiersprache in script JavaScript | VBScript | other code, classid auszuführender Programmcode in applet, object Bezeichner Programmierkurs I (HTML, CSS, Java) - 11 Hypertext Markup Language (HTML) codetype Typ des Programmcodes in applet, object Bezeichner name Metainfo. Bezeichnung, in meta Text http-equiv Metainfo. HTTProtokol, in meta Text content Metainfo. Inhalt, in meta Text lang Sprache in einem Element z.B. en, de dir Textschreibrichtung z.B. ltr, rtl Script-Ereignisse Ereignis Bedeutung onload, onunload Aufruf beim Laden onchange Aufruf bei änderungen onclick Aufruf beim Anklicken onmouseover Maus über dem Element onmouseout Maus verläßt Element onselect bei Auswahl onsubmit beim Versenden Beispiele 3.4. Allgemeines zum Web-Design • Web-Seiten bieten neue Möglichkeiten aber auch Unterschiede z.B. zur Buchproduktion. • Welche Zielgruppe? • auf jeder Seite: Namen, Email, evtl. Copyright, Datum. • Konzept für dauerhafte URLs. • klares, durchsichtiges Hypertext-Konzept, Navigation. • prüfen Sie alle Links. • Navigationshilfen: Home, Site-Map, Stichworte, Suchmöglichkeiten. • gute, einheitliche Gestaltung, klare Farbkonzepte, Farbkontraste (==> CSS). • benutzen Sie Stilvorlagen (CSS). • achte auf Ladezeiten, 30-40KByte ok. • vermeide zu grosse Graphiken, insbesondere auf der Start-Seite. • verwende explizite Grössenangaben bei Tabellen und Graphiken (width, height). • verwende Thumbnails (daumengrosse Mini-Graphiken) mit Link auf die "richtige" Graphik. • beachte auch nicht-visuelle Browser: Lynx, Organizer (alt, summary). • beachte geringere Bildschirmauflösung (640x480, 800x600). • Testen Sie mit unterschiedlichen Browsern. • Testen Sie mit unterschiedlichen Bildschirmauflösungen. • Lassen Sie Ihre Seiten testen. • Halten Sie die Seiten aktuell. Programmierkurs I (HTML, CSS, Java) - 12 Hypertext Markup Language (HTML) • Denken Sie ans Drucken. 3.5. Ausblick • Extensible HTML (XHTML) • HTML-Editoren und Tools • Cascading Style Sheets (CSS) • JavaScript • Document Object Model (DOM) © Universität Mannheim, Rechenzentrum, 1998-2004. Last modified: Wed May 26 23:42:49 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 13 Extensible Hypertext Markup Language (XHTML) 4. Extensible Hypertext Markup Language (XHTML) • HTML als XML Anwendung • HTML Tidy • XHTML Basic 1.0 • XHTML 1.1 4.1. HTML als XML Anwendung • HTML (3.2, 4.0) ist eine SGML Anwendung • XML ist der Standart für erweiterbares Markup • HTML muss in XML reformuliert werden • Version 1.0, W3C Proposed Recommendation August 1999 • HTML 4.01 enthält die notwendigen Anpassungen • im Januar 2000 als W3C Recommendation verabschiedet Warum XHTML? • XHTML Dokumente sind XML konform. Sie können mit XML Tools bearbeitet werden. • XHTML Dokumente können als text/html von HTML 4.0 Browsern verwendet werden. • XHTML Dokumente können aber auch als text/xml oder als application/xml (mit geeigneten Style Sheets) verwendet werden. • XHTML Dokumente können mit DOM bzw. XML-DOM verwendet werden, d.h. mit (Java)Scripts und Applets. • XHTML Dokumente verschiedener Autoren (Systeme, Umgebungen) werden besser zusammenpassen als HTML Dokumente. • Da XHTML eine XML Anwendung ist, können neue Markup-Elemente einfach hinzugefügt werden. • XHTML ist nicht mehr nur auf Browser beschränkt. Viele andere User-Agents (Handys, Sprachausgabe, etc.) werden damit umgehen können (best effort content transformation). Bedingungen für XHTML konforme Dokumente • Sie müssen entsprechend einer XHTML DTD gültige (valid) XML Dokumente sein. • Das Root-Element muss <html> sein. • Das Root-Element muss einen gültigen XHTML Namensraum bestimmen, der ein gültiger XML Namensraum sein muss. • Es muss eine XML DOCTYPE Deklaration vor dem Root-Element verhanden sein. • Die Internet Medien Typen (Mime Types) dürfen text/html, text/xml oder application/xml sein. Beispiel Programmierkurs I (HTML, CSS, Java) - 14 Extensible Hypertext Markup Language (XHTML) <?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/strict.dtd"> <html xmlns="http://www.w3.org/TR/xhtml1"> <head> <title>Browser Titel</title> </head> <body> <h1>Dokument Titel</h1> <p> Ein Paragraph <br /> auf zwei Zeilen. </p> <math xmlns="http://www.w3.org/TR/REC-MathML"> ... Text in MathML ... </math> </body> </html> Verhalten von XML User Agents (Browser) • XML-UAs müssen well-formedness feststellen. • Validierende UAs müssen das Dokument gegen alle DTDs validieren. • Bei unbekannten Elementen muss der Inhalt dargestellt werden (wie bei HTML, nicht bei XML). • Unbekannte Attribute müssen ignoriert werden (wie bei HTML, nicht bei XML). • Bei unbekannten Attribut-Werten muss der Defaultwert verwendet werden (wie bei HTML, nicht bei XML). • Unbekannte Entities müssen als Zeichenkette (&xyz;) dargestellt werden (wie bei HTML, nicht bei XML). • Unbekannte Zeichen (Characters) müssen so dargestellt werden, dass klar ist das sie nicht bekannt, aber erkennbar sind (nicht bei HTML, nicht bei XML). • Whitespace direkt nach einem Start-Tag und unmittelbar vor einem End-Tag muss ignoriert werden (falls nicht per XML etwas anderes bestimmt wurde). Unterschiede zu HTML 4.0 • XHTML Dokumente müssen well-formed sein, d.h. gültige Schachtelungsstruktur haben. <p>Paragraph <em>Hervorhebung</em></p> statt <p>Paragraph <em>Hervorhebung</p></em> • Element- und Attribut-Namen müssen in Kleinbuchstaben geschrieben sein. <li> • statt <LI> End-Tags müssen immer vorhanden sein (falls nicht per XML das Element als EMPTY deklariert wurde). <p>Paragraph</p> <p> weiterer Paragraph</p> statt <p>Paragraph <p> weiterer Paragraph • Bei leeren Elementen ohne End-Tag muss das Start-Tag mit "/>" beendet werden. <br /> • Attributwerte müssen in Anführungszeichen eingeschlossen werden. Auch bei Zahlenwerten. <img ... width="300" /> statt <img ... width=300 /> Programmierkurs I (HTML, CSS, Java) - 15 Extensible Hypertext Markup Language (XHTML) • Attributwerte müssen immer angegeben werden. <dl compact="compact" > statt <dl compact > • In Attributwerten wird Whitespace auf jeweils ein Blank verkürzt, bzw. am Beginn und Ende von Zeichenketten abgeschnitten. alt=" Beschreibung eines Bildes " wird zu alt="Beschreibung eines Bildes" • Script-Texte müssen als CDATA markiert werden, falls sie < oder & enthalten. <script> <![CDATA[ ... Inhalt des Scripts ]]> </script> • SGML Ausschluss-Definitionen sind nur informell festgelegt. z.B. das a-Element darf kein weiteres a-Element enthalten. • Das name Attribut von HTML muss als XML id Attribut angegeben werden. <a name="section1" id="section1" ... > Diese Datei in XHTML und als XML. Tips und Hinweise • Processing Instructions und Zeichensätze werden nicht von allen UAs erkannt <?... >, UTF-8, UTF-16. • Benutze Blanks vor /> Benutze <br /> statt <br></br> Benutze <p></p> statt <p />. • Benutze externe Scripte, falls "<", "&" oder "]]>" vorkommen. • Verwende keine Zeilenumbrüche und mehrfache Leerzeichen in Attribut werten. • Benutze lang und xml:lang gleichzeitig als Attribute. • Benutze name="xyz" und id="xyz" gleichzeitig als Attribute für die Bezeichnung von Elementen. • Benutze <?xml ... encoding="iso-8859-1"> und <meta http-equiv="Content-type" ... charset="iso-8859-1"> gleichzeitig für die Bezeichnung von Zeichensätzen. • Einige UAs haben Probleme mit Booleschen Attributen. • Problem bei DOMs: HTML 4.0 DOM benutzt Grossbuchstaben, XHTML 1.0 DOM benutzt Kleinbuchstaben, XML 1.0 DOM benutzt Gross-/Klein-Buchstaben. • Problem mit "&" in Attributwerten, z.B. href=".../script.pl?n1=w1&amp;n2=w2" • Probleme mit Style Sheets (CSS): Gross-/Klein-Schreibung von Elementen. Ausblick • Modularisierung von XHTML, d.h. zuschneiden auf bestimmte UAs Programmierkurs I (HTML, CSS, Java) - 16 Extensible Hypertext Markup Language (XHTML) • Formalisieren der Bildung von Teilmengen und Erweiterungen. • Dokument Profile • Stand im Mai 2003 • XHTML Basic, 2000 Dezember • XHTML 1.1 - Module based XHTML, 2001 Mai • XHTML 2.0, Working Draft, 2003 Januar 4.2. HTML Tidy • Tool zur Fehlersuche in HTML • bietet auch Fehlerkorrektur • kann Müll von HTML-Editoren entfernen • kann HTML nach XHTML konvertieren • offizielles Tool des W3C • erkennt, prüft und korrigiert Dokumenttyp • für fast alle Plattformen verfügbar • Unterstützung von XML, ASP, PHP Beispiele für die Arbeitsweise von HTML Tidy Beispiel für schlechtes HTML bad.html und das Ergebnis nach Bearbeitung mit HTML Tidy good.html. Fehlermeldungen aus dem Beispiel > tidy Tidy line line line line line line line line line line line line line line line exam/bad.html >exam/good.html (vers 19th October 1999) Parsing "exam/bad.html" 3 column 1 - Warning: inserting missing 'title' element 5 column 2 - Warning: replacing unexpected <h2> by </h1> 5 column 37 - Warning: discarding unexpected </h3> 7 column 42 - Warning: replacing unexpected </i> by </b> 8 column 15 - Warning: replacing unexpected </b> by </i> 10 column 45 - Warning: missing </i> before </h2> 12 column 4 - Warning: inserting implicit <i> 14 column 2 - Warning: missing </i> before <p> 14 column 4 - Warning: inserting implicit <i> 14 column 43 - Warning: discarding unexpected <a> 16 column 2 - Warning: missing </a> before <li> 16 column 2 - Warning: missing </i> before <li> 16 column 2 - Warning: inserting implicit <ul> 24 column 1 - Warning: unknown attribute "tidy" 30 column 1 - Warning: <img> lacks "alt" attribute "exam/bad.html" appears to be HTML proprietary 15 warnings/errors were found! Programmierkurs I (HTML, CSS, Java) - 17 Extensible Hypertext Markup Language (XHTML) The alt attribute should be used to give a short description of an image; longer descriptions should be given with the longdesc attribute which takes a URL linked to the description. These measures are needed for people using non-graphical browsers. For further advice on how to make your pages accessible see "http://www.w3.org/WAI/GL". You may also want to try "http://www.cast.org/bobby/" which is a free Web-based service for checking URLs for accessibility. HTML & CSS specifications are available from http://www.w3.org/ To learn more about Tidy see http://www.w3.org/People/Raggett/tidy/ Please send bug reports to Dave Raggett care of <[email protected]> Lobby your company to join W3C, see http://www.w3.org/Consortium Aufruf und Verwendung von HTML Tidy > tidy [[options] files]* tidy: file1 file2 ... Utility to clean up & pretty print html files see http://www.w3.org/People/Raggett/tidy/ options for tidy released on 19th October 1999 -config <file> set options from config file -indent or -i indent element content -omit or -o omit optional endtags -wrap 72 wrap text at column 72 (default is 68) -upper or -u force tags to upper case (default is lower) -clean or -c replace font, nobr & center tags by CSS -raw leave chars > 128 unchanged upon output -ascii use ASCII for output, Latin-1 for input -latin1 use Latin-1 for both input and output -iso2022 use ISO2022 for both input and output -utf8 use UTF-8 for both input and output -mac use the Apple MacRoman character set -numeric or -n output numeric rather than named entities -modify or -m to modify original files -errors or -e only show errors -quiet or -q suppress nonessential output -f <file> write errors to <file> -xml use this when input is wellformed xml -asxml to convert html to wellformed xml -slides to burst into slides on h2 elements -help or -h list command line options Input/Output default to stdin/stdout respectively Single letter options apart from -f may be combined as in: tidy -f errs.txt -imu foo.html For further info on HTML see http://www.w3.org/MarkUp Einige wichtige Optionen markup: yes, no Erzeugen des verbesserten Markups. wrap: number Zeilenumbruch bei angegebener Spalte. 0 = abgeschaltet. input-xml: yes, no Einlesen als XML. output-xml: yes, no Ausgabe von XML. output-xhtml: yes, no Ausgabe von XHTML. doctype: omit, auto, strict, loose or <fpi> Programmierkurs I (HTML, CSS, Java) - 18 Extensible Hypertext Markup Language (XHTML) Festlegen des DOCTYPE in der Ausgabe. char-encoding: raw, ascii, latin1, utf8 or iso2022 Festlegen des Zeichensatzes in der Ausgabe. fix-backslash: yes, no Wandelt "\" in URLs zu "/". word-2000: yes, no Versucht Müll, der von Word 2000 produziert wird zu entfernen. clean: yes, no Versucht überflüssigen Präsentations-Markup durch Stilregeln (CSS) oder Struktur-Markup zu ersetzen. logical-emphasis: yes, no Ersetzt i durch em, b durch strong, impliziert clean. enclose-text: yes, no Fasst Text auf Body-Level in Paragraphen. Wichtig für funktionierende Stilvorlagen. split: yes, no Teilt die Datei an h2 Elementen in einzelne "Folien". new-empty-tags: tag1, tag2, tag3 new-inline-tags: tag1, tag2, tag3 new-blocklevel-tags: tag1, tag2, tag3 new-pre-tags: tag1, tag2, tag3 Definition von neuen Tags der entsprechenden Art. Beispiel für ein Config-File /* HTML Tidy configuration file */ markup: yes wrap: 0 doctype: strict break-before-br: yes logical-emphasis: yes enclose-text: yes /* eof */ Was in Arbeit ist • Validierung aller Attribute • Verbesserter XML Support • Verbesserung der Zeichensatz Unterstüzung • Verbesserung der ASP und PHP Unterstüzung • Verbesserte Folien Erzeugung 4.3. XHTML Basic 1.0 Reduktion von XHTML 1.0 auf die Elemente und Attribute, die auch auf kleinen Geräten angezeigt werden können. Zum Beispiel • Handys • Fernseher • PDAs • Verkaufsautomaten • Pager Programmierkurs I (HTML, CSS, Java) - 19 Extensible Hypertext Markup Language (XHTML) • Fahrzeug Navigationssysteme • Spielekonsolen • Lesegeräte für digitale Bücher • Uhren mit CPUs Die gemeinsame Fähigkeiten dieser einfachen UAs ermöglichen folgende XHTML Elemente. • einfacher Text (mit Überschriften, Paragraphen und Listen) • Hyperlinks (a und link) • einfache Formulare • einfache Tabellen • Bilder • Meta-Information Elemente und Attribute, die nur auf aktuellen grafischen (PC-) Systemen funktionieren sind weggelassen. • keine Stilvorlagen (CSS) • keine Scripte (JavaScript) und zugehörige Attribute • nur einfache Fonts (Schreibmaschinenschriften) • kein File-Upload und Bilder in Formularen • keine geschachtelten Tabellen • keine Frames Der Document Type ist <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd"> Definierte Module Structure Module* body, head, html, title Text Module* abbr, acronym, address, blockquote, br, cite, code, dfn, div, em, h1, h2, h3, h4, h5, h6, kbd, p, pre, q, samp, span, strong, var Hypertext Module* a List Module* dl, dt, dd, ol, ul, li Basic Forms Module form, input, label, select, option, textarea Basic Tables Module caption, table, td, th, tr Image Module img Object Module object, param Metainformation Module meta Link Module Programmierkurs I (HTML, CSS, Java) - 20 Extensible Hypertext Markup Language (XHTML) link Base Module base (*) = diese Module müssen bei XHTML Basic 1.0 mindestens unterstützt werden. XHTML Basic 1.0 konformes Beispiel 4.4. XHTML 1.1 - Modul basiertes XHTML Neuordnung von striktem XHTML 1.0 mit Hilfe von Modulen. Der Dokumenttyp ist <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> Definierte Module Structure Module* body, head, html, title Text Module* abbr, acronym, address, blockquote, br, cite, code, dfn, div, em, h1, h2, h3, h4, h5, h6, kbd, p, pre, q, samp, span, strong, var Hypertext Module* a List Module* dl, dt, dd, ol, ul, li Object Module object, param Presentation Module b, big, hr, i, small, sub, sup, tt Edit Module del, ins Bidirectional Text Module bdo Forms Module button, fieldset, form, input, label, legend, select, optgroup, option, textarea Table Module caption, col, colgroup, table, tbody, td, tfoot, th, thead, tr Image Module img Client-side Image Map Module area, map Server-side Image Map Module Attribut ismap von img Intrinsic Events Module Event Attribute Metainformation Module meta Programmierkurs I (HTML, CSS, Java) - 21 Extensible Hypertext Markup Language (XHTML) Scripting Module noscript, script Stylesheet Module style element Style Attribute Module Deprecated style attribute Link Module link Base Module base Ruby Annotation Module ruby, rbc, rtc, rb, rt, rp Weitere Änderungen gegenüber XHTML 1.0 Strict sind: lang wird ersetzt durch xml:lang und name wird ersetzt durch id. XHTML 1.1 konforme Beispiele: basic, alles. © Universität Mannheim, Rechenzentrum, 1998-2004. Last modified: Sat May 22 12:35:56 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 22 Cascading Style Sheets (CSS) 5. Cascading Style Sheets (CSS) • Einordnung • Grundkonzepte von CSS • Layout mit CSS1 • Beispiele und Hinweise 5.1. Einordnung Layouts für Web-Publishing Trennung von Struktur und Präsentation wird möglich • CSS1, CSS2 Cascading Style Sheets, Level 1 & Level 2 zu HTML • DSSSL Document Style Semantics and Specification Language zu SGML • XSL Extensible Style Language zu XML Stand der Entwicklung: • CSS1: W3C Recommendation, Dezember 1996 • CSS2: W3C Recommendation, Mai 1998 • CSS3: W3C Proposed Recommendation, 1999 • Browser wie die von Netscape oder Microsoft implementieren nur ca. 30% bis 80% der Spezifikation korrekt • aber alle Hersteller haben sich zur Unterstützung von CSS1 verpflichtet Programmierkurs I (HTML, CSS, Java) - 23 Cascading Style Sheets (CSS) 5.2. Grundkonzepte von CSS • CSS Regeln: element { property: value } body { background-color: white } • Selektoren und Deklarationen • Eigenschaften (properties) und Werte • Regeln in eigener Datei oder in HTML eingebettet • Gruppierung: h1, h2, h3 { font-family: helvetica } h4 • { color: red; font-size: 8pt; } Kontext: h1 { color: red } Programmierkurs I (HTML, CSS, Java) - 24 Cascading Style Sheets (CSS) h1 em { color: purple } h1 em strong { color: fuchsia } • Vererbung: body { font-family: helvetica } h1 { color: red; font-size: 14pt; } z.B. Schriftfamilie wird auf enthaltene Elemente vererbt • Cascadierung: em { font-style: italic } p em { font-weight: bolder } strong em { font-weight: bold } h1 em { font-style: normal } • CSS ist "Fehlertolerant" wie HTML • Gross-/Kleinschreibung wird ignoriert Elemente für die kein Stil definiert wird, werden mit dem Browser Default-Stil dargestellt. Verknüpfung mit HTML • im link Element: <link rel="stylesheet" type="text/css" href="http://host/path/file.css"> • im style Element: <style type="text/css"> h3 { color: lime } </style> • mit @import: <style type="text/css"> @import url(http://style.org/company.css) h1 { color: lime } </style> • als Attribut: <p style="color: red" > roter Text </p> dies sollte man nicht machen Element-Typen Block-Elemente blockquote, br, dd, dl, div, dt, hi, hr, html, li, object, ol, p, pre, ul Inline-Elemente a, em, i, img, span, strong, tt Unsichtbare Elemente Programmierkurs I (HTML, CSS, Java) - 25 Cascading Style Sheets (CSS) link, meta, style, title Auswahl mit Bezeichnern • class, mehrfachverwendbare Bezeichner: h1.slide { color: lime } p.slide { color: green } .buch1 { color: yellow; background-color: black } <h1 class="slide">BlaBla</h1> <h1 class="buch1">BluBlu</h1> • id, eindeutige Bezeichner: #sp3 { color: aqua } <h1 id="sp3">BlaBla</h1> • Pseudo-Klassen: a:link a:visited a:active a:hover • { { { { color: color: color: color: red } /* unvisited */ blue } red } purple } /* mouseover */ Pseudo-Elemente: p:first-line { color: fuchsia } p:first-letter { color: red; background-color: lime } • Sehr wichtige Definition: h1.slide { color: fuchsia !important } Algorithmus der Cascadierung Es wird die anzuwendende Element-Eigenschaft Kombination gesucht: 1. Element entsprechend dem Selektor oder Vererbung 2. entsprechend explizitem Gewicht: !important geht vor 3. entsprechend dem Ursprung: Autor vor Benutzer vor Browser 4. entsprechend dem Detail-Level (specificity): umgekehrt lexikographisch: (IDs, CLASSes, TAGnumber) li ul li ul ol li li.rum ul li.rum ul.uni li.rum #hpc { { { { { { { prop: prop: prop: prop: prop: prop: prop: .1. .2. .3. .4. .5. .6. .7. } } } } } } } --> --> --> --> --> --> --> (0,0,1) (0,0,2) (0,0,3) (0,1,1) (0,1,2) (0,2,2) (1,0,0) <li id="hpc" > .7. gewinnt </li> <li class="rum"> .4., .5. oder .6. gewinnt </li> <li > .1., .2. oder .3. gewinnt </li> 5. entsprechend der Reihenfolge Beispiel: Header von HTML 2.0 in CSS1 Programmierkurs I (HTML, CSS, Java) - 26 Cascading Style Sheets (CSS) h1, h2, h3, h4 { margin-top: 1em; margin-bottom: 1em } h5, h6 { margin-top: 1em } h1 { text-align: center } h1, h2, h4, h6 { font-weight: bold } h3, h5 { font-style: italic } h1 { font-size: xx-large } h2 { font-size: x-large } h3 { font-size: large } Algorithmus der Cascadierung in CSS2 Die Punkte 2 und 3 werden zu einem zusammengefasst. 1. entsprechend dem Ursprung: Autor vor Benutzer vor Browser aber bei Angabe von !important gilt: Benutzer vor Autor vor Browser 5.3. Layout mit CSS1 Schriften Liegen in verschiedenen Schnitten (Gestalt mit bestimmten Eigenschaften) vor. Die Schrift-Eigenschaften sind nicht einfach berechenbar (vergleiche TeX und Metafont). • Schrift-Familie: font-family Helvetica, Times, Western, Courier sans-serif, serif, fantasy, monospace • Schrift-Stil: font-style normal, italic • Schrift-Variante: font-variant normal, small-caps • Schrift-Gewicht: font-weight normal, bold, lighter, 100, ..., 900 (sehr fett) • Schrift-Grösse: font-size absolut: xx-small, x-small, small, medium, large, x-large, xx-large 12pt, 18pt, 10px, 1.0cm, 1.0in relativ: 150%, 0.5em (Höhe M), 0.7ex (Höhe x) • Schrift: font: style variant weight size/height family zusammenfassende Deklaration Beispiel p { font-family: monospace; font-size: x-large; } So siehts aus. Beispiele font-family: Times, Helvetica, Verdana, Western, Courier, Zapf Chancery, Programmierkurs I (HTML, CSS, Java) - 27 Cascading Style Sheets (CSS) serif, sans-serif, monospace, cursive, fantasy. Beispiele font-style: normal, oblique, italic. Beispiele font-variant: normal, Small-Caps. Beispiele font-weight: normal, bold, bolder, lighter, 100, ..., 400, ..., 900. Beispiele font-size: xx-small, x-small, small, medium, large, x-large, xx-large, 2.0cm, 1.0in, 14pt, 34pt, 30px, 120%, 2.0em, 1.5ex. Farben • RGB-Farbmodell: Rot, Grün, Blau bei Computer Bildschirmen • CMYK-Farbmodell: Cyan, Magenta, Yellow, Black bei Farbdruckern • Farben: black, silver, gray, white, maroon, red, purple, fuchsia, green, lime, olive, yellow, navy, blue, teal, aqua rgb(rot,grün,blau), Werte: 0 <= rot, grün, blau <= 255, oder 0% <= rot, grün, blau <= 100% #rgb, oder #rrggbb, Werte: 0 <= r, g, b <= F • Schriftfarbe: color • Hintergrundfarbe: background-color • Hintergrundbild: background-image url(http://host/pfad/bild) p { color: blue } Schwarz, Hellgrau, Grau, Weiß, Dunkelrot, Rot, Purpur, helles Purpur, Grün, Hellgrün, dunkles Grün, Gelb, Dunkelblau, Blau, Blaugrün, helles Grünblau (Cyan). weitere Eigenschaften Box-Eigenschaften: Füllung (padding), Rahmen (border), Rand (margin) Box mit was drin Programmierkurs I (HTML, CSS, Java) - 28 Cascading Style Sheets (CSS) Quelle: W3C, CSS2 Spezifikation • Box-Eigenschaften: margin, margin-top, margin-right, margin-bottom, margin-left padding, border, border-color, border-style width, height • Text-Eigenschaften: word-spacing, white-space: pre, nowrap, text-decoration: underline, blink, text-transform: capitalize, uppercase, lowercase • Text-Ausrichtung: vertical-align, text-align, text-indent, line-height • Hintergrundbilder: background-image: url(...) background-repeat, background-attachment, background-position 5.4. Beispiele und Hinweise Programmierkurs I (HTML, CSS, Java) - 29 Cascading Style Sheets (CSS) Beispiele vom W3C HTML 2.0 in CSS1: /* Copyright (c) 1998 W3C */ BODY { margin: 1em; font-family: serif; line-height: 1.1; background: white; color: black; } H1, H2, H3, H4, H5, H6, P, UL, OL, DIR, MENU, DIV, DT, DD, ADDRESS, BLOCKQUOTE, PRE, BR, HR { display: block } B, STRONG, I, EM, CITE, VAR, TT, CODE, KBD, SAMP, IMG, SPAN { display: inline } LI { display: list-item } H1, H2, H3, H4 { margin-top: 1em; margin-bottom: 1em } H5, H6 { margin-top: 1em } H1 { text-align: center } H1, H2, H4, H6 { font-weight: bold } H3, H5 { font-style: italic } H1 { font-size: xx-large } H2 { font-size: x-large } H3 { font-size: large } B, STRONG { font-weight: bolder } /*relative to the parent*/ I, CITE, EM, VAR, ADDRESS, BLOCKQUOTE { font-style: italic } PRE, TT, CODE, KBD, SAMP { font-family: monospace } PRE { white-space: pre } ADDRESS { margin-left: 3em } BLOCKQUOTE { margin-left: 3em; margin-right: 3em } UL, DIR { list-style: disc } OL { list-style: decimal } MENU { margin: 0 } LI { margin-left: 3em } /* tight formatting */ DT { margin-bottom: 0 } DD { margin-top: 0; margin-left: 3em } HR { border-top: solid } A:link { color: blue } A:visited { color: red } A:active { color: lime } /* unvisited link */ /* visited links */ /* active links */ /* setting the anchor border around IMG elements requires contextual selectors */ A:link IMG { border: 2px solid blue } A:visited IMG { border: 2px solid red } A:active IMG { border: 2px solid lime } Beispiele für Basis-HTML Beispiel mit einfachen Hervorhebungen. Stile aus der W3C Style Gallery • Alle Stile in einem Frameset: Multi Programmierkurs I (HTML, CSS, Java) - 30 Cascading Style Sheets (CSS) • "Choclate" Stil: HTML, CSS. • "Midnight" Stil: HTML, CSS. • "Modernist" Stil: HTML, CSS. • "Oldstyle" Stil: HTML, CSS. • "Steely" Stil: HTML, CSS. • "Swiss" Stil: HTML, CSS. • "Traditional" Stil: HTML, CSS. • "Ultramarine" Stil: HTML, CSS. Beispiele aus dem Web • W3C Style Gallery: http://www.w3.org/StyleSheets/Core/ • Genug ist Genug: by Stephen Traub • Microsoft CSS Gallery: Entrance Hinweise zur effektiven Nutzung von CSS Alles was mit CSS1 machbar ist, ist in HTML 4.0 "deprecated", d.h. nicht mehr empfohlen, d.h. zur Nicht-Benutzung empfohlen. • Benutze nur wenige zentrale Stile, am Besten ein Stil für alle Web-Seiten. • Benutze nur gelinkte Stildateien. • Benutze nur in Ausnahmefällen zusätzliche spezielle Stildateien. • Lasse den Stil von einem Experten designen. • Propagiere den Stil, biete gute Dokumentation. • Beachte, dass die Web-Seiten auch noch gut aussehen, falls der Browser (UA) kein CSS kann. • Benutze nicht mehr als zwei Fonts. • Benutze relative Fontgrössen (200%,50%). • Lasse !important für den Leser. Beschränkungen von CSS1 Eine Übersicht über den Grad der Unterstützung von CSS(1) befand sich bis 2003 zum Beispiel bei http://webreview.com/style/ unter dem Punkt 'Master list'. Die Liste ist heute (2004) nicht mehr notwendig und auch nicht mehr auffindbar. • keine freie Positionierung • keine volle Autoren-Kontrolle • keine mehrfachen Spalten • keine mehreren Schichten (Layers) • Drucken verbesserungsfähig • keine Sprachausgabe-Layouts © Universität Mannheim, Rechenzentrum, 1998-2004. Last modified: Thu May 20 12:28:29 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 31 Cascading Style Sheets (CSS) Programmierkurs I (HTML, CSS, Java) - 32 Cascading Style Sheets 2 (CSS2) 6. Cascading Style Sheets 2 (CSS2) • CSS Level 2 • Ausblick 6.1. CSS Level 2 • Positionierung • Medientypen: Sprache, Drucker, Folien • Schriftauswahl, Download • Auto-Numerierung • Tabellen Beispiel: Style Sheet für HTML 4.0 in CSS2 Positionierung Ab Netscape 4.x, IE 4.0, 5.0 implementiert CSS-P = CSS1 + Positionierung • Box-Position: position: static, relative, absolute, fixed static = normaler Elementfluss relative = zunächst wie static, dann relativ zu dieser Position absolute = unabhängig vom Elementfluss an einer festen Stelle im Dokument fixed = unabhängig vom Elementfluss an einer festen Stelle im Fenster • left: length • top: length • height: length • width: length • z-index: integer • visibility: hidden, visible Animation mit HTML, CSS, JavaScript und DOM Dateien: HTML, CSS, JavaScript. Medientypen Programmierkurs I (HTML, CSS, Java) - 33 Cascading Style Sheets 2 (CSS2) • screen: Bildschirmausgabe • print: Druckausgabe • aural: Sprachausgabe • braille: Blindenschrift • embossed: Blindenschrift-Drucker • handheld: Mobilfunk, Handy • projection: Projektor, Video-Beamer • tty: Text-Bildschirm • tv: TV-Bildschirm Beispiel: @media print { body { font-size: 10pt } } @media screen { body { font-size: 12pt } } Mediengruppen • continous oder paged • visual oder aural oder tactile • grid oder bitmap • interactive oder static neue Selektoren für Attribute p[align] { font-style: italic; } p[align="center"] { font-style: italic; align: center; } p[align~="center"] { font-style: italic; align: center; } für Kinder und nebeneinanderstehende Elemente p > em { font-style: italic; } h1 + h2 { margin-top: -5mm; } für Sprachauswahl p:lang(de) p:lang(fr) { font-family: sans-serif; } { font-family: serif; } neue Pseudo-Elemente h1:before p:after { content: counter(kapitel) ". "; } { content: " © BWL 1999"; } neue Display-Typen Programmierkurs I (HTML, CSS, Java) - 34 Cascading Style Sheets 2 (CSS2) h3 dt tr { display: run-in; } { display: compact; } { display: table-row; } Fliesstext img img.x p { float: left; } { float: right; } { clear: left; } Erweiterungen bei Fonts • font-stretch: Dehnungsverhalten normal, wider, narrower, condensed, expanded • font-size-adjust: Angleichung der Zeichengrössen zwischen verschiedenen Fonts, Aspekt-Wert • @font-face Beschreibung und Auswahl von Fonts @font-face { font-family: "Robson Celtic"; src: url("http://host/fonts/rob-celt"); } p.rc { font-family: "Robson Celtic"; } Fontauswahl • Auswahl per Fontname Problem: es gibt kein anerkanntes Namensschema • Auswahl "ähnlicher" Fonts (intelligent font matching) • Erzeugung von Fonts (font synthesis) • Download von Fonts @font-face • alle Eigenschaften von Fonts können verwendet werden • font-family, font-style, font-variant, font-weight, font-stretch, font-size • zusätzlich kommen neue Deskriptoren hinzu: • uni-code-range: Bereich vorhandener Zeichen (glyphs) U+0-7FFFFFFF • units-per-em: Anzahl der Einheiten per 'em' • src: URL (zum Download) oder Bezeichnung für einen Font src: local("Verdana"), url("../fonts/verdana") format("type-1") • Deskriptoren für Fontauswahl panose-1: 0 0 0 0 0 0 0 0 0 0 Panose-1 Nummer stemv: vertikaler Stem-Wert ("M", em, Höhe des grossen M) stemh: horizontaler Stem-Wert ("x", ex, Höhe des kleinen x) slope: Neigungswinkel cap-height: Grösse der Grossbuchstaben x-height: Grösse der Kleinbuchstaben ascent: Grösse der Buchstaben ohne Akzente descent: Grösse der Buchstaben ohne untere Akzente Programmierkurs I (HTML, CSS, Java) - 35 Cascading Style Sheets 2 (CSS2) • Deskriptoren für Fontsynthese width: Breite von Buchstaben bbox: maximaler Umriss von Buchstaben definition-src: definiert wo die Spezifikation zu finden ist • Deskriptoren für Ausrichtung von Fonts untereinander baseline: untere Basisline der Schrift centerline: Mittelline der Schrift mathline: Ausrichtung der mathematischen Zeichen topline: obere Basisline der Schrift • die Auswahl geeigneter Fonts erfolgt durch einen (längeren) Algorithmus Beispiel @font-face { font-family: "Swiss 721 Condensed"; src: url("http://host/fonts/swiss721co.pfr"); font-style: normal, italic; font-stretch: condensed; } p.sc { font-family: "Swiss 721 Condensed"; } Zähler und Textersetzungen • Pseudo-Elemente :before, :after • Textersetzungen content: "string", URL, counter(cnt), attr(X), open-quote, close-quote • Initialisieren von Zählern counter-reset: cnt • Weiterzählen counter-increment: cnt • Zähler-Format counter( name, type ) disk, circle, square, upper-latin, hebrew, upper-roman • Einrückungen für Zähler marker-offset: @media aural { blockquote { content: url("bq-music.wav"); } } h1:before { content: "Kapitel " counter(kapitel) ". "; counter-increment: kapitel; counter-reset: abschn; } h2:before { content: counter(kapitel) "." counter(abschn) ". "; } counter-increment: abschn; Stile für Drucker • Druckseiten @page { ... } • Seitengrösse size: • Ränder margin: • für linke und rechte Seiten :left, :right • Seitenumbruch page-break-before: page-break-after: page-break-inside: auto, always, avoid, left, right Programmierkurs I (HTML, CSS, Java) - 36 Cascading Style Sheets 2 (CSS2) • Seitenumbruch in Paragraphen Anzahl Zeilen am Fuss orphans: int Anzahl Zeilen am Kopf widows: int @media print { @page { size: auto; margin: 10%; } @page :right { margin-left: margin-right: } @page :left { margin-left: margin-right: } } 10; 5; 5; 10; Stile für Tabellen • zugeschnitten für das HTML 4.0 Tabellenmodell • rechteckige Anordnung von Zellen • zeilenweise Anordnung Beispiel für Tabelle Spalte 1 1 Spalte 2 2 4 Spalte 3 3 6 <table class="exam" border="1" cellpadding="10" cellspacing="10" summary="HTML Elemente"> <tr> <th>Spalte 1</th><th>Spalte 2</th><th>Spalte 3</th> </tr> <tr> <td>1</td><td>2</td><td>3</td> </tr> <tr> <td>4</td><td></td><td>6</td> </tr> <caption>Beispiel für Tabelle</caption> </table> mit folgendem Style Sheet table.exam { font-size: large; background-color: lime; } table.exam td { text-align: center; color: red; } table.exam caption { caption-side: right; color: blue; } freidefinierbare Tabellen-Elemente Neue display: Werte ermöglichen Tabelleneigenschaften für beliebige Elemente, wichtig für XML (Auswahl). Programmierkurs I (HTML, CSS, Java) - 37 Cascading Style Sheets 2 (CSS2) • table wie table in HTML 4.0 • table-row wie tr • table-column wie col • table-cell wie td, th • table-caption wie caption table tr th, td col caption { { { { { display: display: display: display: display: table } table-row } table-cell } table-col } table-caption } weitere Tabellen-Eigenschaften • Grundlayout table-layout: auto | fixed • Ausrichtung an bestimmten Zeichen text-align: "." • Rand-Modelle border-collapse: collapse, separate • Ränder border-spacing: len • leere Zellen empty-cells: show, hide • Randstil border-style: solid, dotted, groove, ridge • Sprachausgabe speak-header: once, always td { text-align: "," } td:before { content: "€" } table { empty-cells: show } Stile für Sprachausgaben Eigenschaften: Umgebung-/Raumabhängigkeit, Zeitabhängigkeit, Sprachqualität. • Lautstärke volume: soft | loud | x% • Sprechart speak: normal | spell-out • Pausen pause-before: zeit pause-after: zeit pause: before after • "Ton-Icons" = Cue cue-before: url(.) cue-after: url(.) cue: before after • Gleichzeitiges Abspielen play-during: url(.) mix? repeat? • Räumliche Eigenschaften azimuth: Raumseitenwinkel, behind, left, right elevation: Raumhöhenwinkel, below, above Programmierkurs I (HTML, CSS, Java) - 38 Cascading Style Sheets 2 (CSS2) • weitere Eigenschaften speech-rate: slow | fast, Worte pro Minute (180-200), voice-family: male | female | 'speaker', pitch: freq, Frequenz (120Hz) pitch-range: , stress: int, Betonung richness: int, "Fülle" speak-punctuation: code | none, speak-numeral: digits | continous @media aural { h2 { pause: 30ms 40ms; } a { cue-before: url("a-bell.wav"); } em { play-during: url("em-sound.wav") mix repeat; } p.note { azimuth: behind; } p.dog { elevation: below; } } Weitere Änderungen gegenüber CSS1 • Berücksichtigung der Text-Schreibrichtung direction: ltr|rtl • Behandlung von Text-Ausschnitten clip: shape, overflow: scroll • Cursor Darstellung cursor: crosshair | text | wait | url(.) Beispiele Beispiel mit CSS Level 2 Konstrukten. 6.2. Ausblick CSS3 • Paged Media Support, z.B. WAP auf Handys • DOM Level 2 Support • Scalable Vector Graphics (SVG) • User Interface, z.B. "Kiosk" Mode • International Layout, z.B. Arabisch, Japanisch • Multicolumn Layout XSL • CSS und XML • XSL • XSLT © Universität Mannheim, Rechenzentrum, 1998-2004. Programmierkurs I (HTML, CSS, Java) - 39 Cascading Style Sheets 2 (CSS2) Last modified: Sat May 22 12:36:17 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 40 Java, Einleitung 7. Java, Einleitung • Einleitung • "Hallo Welt" • Software-Entwicklung 7.1. Einleitung • Programmiersprache der Firma SUN • vollständige objektorientierte Programmiersprache • Syntaktisch an C++ angelehnt • Objekte, Klassen, Kapselung • Vererbung, Polymorphismus • multi-threaded • hierarchisches Modulkonzept package • Interpreter • Unterschiede zu anderen OO-Sprachen • einfach, Verzicht auf wenig genutzte höhere Sprachkonzepte • teilcompilierend, Byte-Code kann auf jeder Plattform mit einer Implementierung der zu Java gehörenden 'Virtual Machine' ablaufen • dynamisches Laden von Klassen • sehr sehr umfangreiche Bibliotheken als Teil der Sprachdefinition • Sicherheit • Konkurenzprodukt: C# mit CRI seit 2002 • Java als "Web-Programmiersprache" • Virtual Machine ist in vielen gängigen Web-Browsern verfügbar • einfache Integration mit HTML • Bibliotheken für graphische Oberflächenelemente (AWT und Swing) ist Teil der Laufzeit-Umgebung • Bibliothek für Netzwerk-Programmierung ist Teil der Laufzeit-Umgebung • dynamisches Laden von Klassen ermöglicht effiziente Nutzung von niedriger Netz-Bandbreite • Mechanismen zur Unterscheidung zwischen "vertrauenswürdigem" und sogenannten "untrusted" Code sind Teil der Sprachdefinition und Laufzeitumgebung Programmierkurs I (HTML, CSS, Java) - 41 Java, Einleitung 7.2. "Hallo Welt" Ein erstes Java-Beispiel Das einfachste, immer wieder eingesetzte Programm zeigt nur "Hallo Welt !" an. import java.awt.*; import java.applet.*; public class HelloWorldApplet extends Applet { String msg = ""; public void init () { msg = "Hallo Welt !"; } public void paint(Graphics g) { g.drawString(msg,10,75); } } Ein solches Java-Programm wird in einen sogenannten Byte-Code kompiliert und dann mit Hilfe eines Java-Interpreters, des Appletviewers oder der Web-Browsers ausgeführt. Die Kompilierung mit dem Byte-Code Compiler erfolgt durch javac. % javac HelloWorldApplet.java Die Ausführung erfolgt mit dem Appletviewer oder dem Web-Browser. % appletviewer helloworld.html Die zugehörige HTML Seite sieht wie folgt aus. <html> Programmierkurs I (HTML, CSS, Java) - 42 Java, Einleitung <head><title>Simple Applet</title> </head> <body bgcolor="white"> <applet code="HelloWorldApplet.class" width="150" height="150"> </applet> </body> </html> Das Ergebnis ist wie erwartet. Swing Applet import javax.swing.*; import java.awt.*; public class HelloWorldAppletSwing extends JApplet { JTextPane anzeige; String msg = ""; public void init () { msg = "\nHallo Welt !\n"; anzeige = new JTextPane(); anzeige.setText(msg); Container c = getContentPane(); c.add(anzeige,BorderLayout.CENTER); } } Das Ergebnis. Kommandozeilen Java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } Vor der Kompilation müssen bei älteren JDKs einige Umgebungsvariablen gesetzt werden. Dies sind die Variablen CLASSPATH und PATH, die unter Unix/Linux in den Shells sh oder bash, wie folgt gesetzt werden. % set CLASSPATH="/usr/local/jdk/java/lib:." % set PATH="$PATH:/usr/local/jdk/java/bin" % export CLASSPATH PATH Diese Zeilen können eingetippt oder in der Datei .bashrc dauerhaft eingetragen werden. Auf Windows-NT-Rechnern müssen diese Variablen im Systempanel entsprechend gesetzt werden. Dabei ist das Trennzeichen `:' durch `;' und das Pfadtrennzeichen `/' durch `\' zu ersetzen. In anderen Umgebungen müssen Sie die Umgebungsvariablen entsprechend anpassen, falls sie nicht schon durch die Installationsroutinen richtig eingestellt werden. Die Kompilierung mit dem Byte-Code Compiler erfolgt durch javac. % javac HelloWorld.java Die Ausführung erfolgt mit dem Interpreter java. % java HelloWorld Programmierkurs I (HTML, CSS, Java) - 43 Java, Einleitung Das Ergebnis ist wie erwartet. Hello World! Andere Programmiersprachen Scheme / LISP: (display "Hello World!") oder ((lambda (p) (begin (display "Hallo Welt von ") (display p) (display "!")) ) "Heinz" ) Hallo Welt von Heinz! oder (define (hallo p) (begin (display "Hallo Welt von ") (display p) (display "!")) ) (hallo "Anja") Hallo Welt von Anja! Pascal: program HelloWorld(output); begin writeln('Hello world!'); end. C: #include <stdio.h> int main() { printf("Hello world!"); return 0; } C++: #include <cstdio> int main() { std::out<<"Hello world!"; return 0; } C++: Programmierkurs I (HTML, CSS, Java) - 44 Java, Einleitung #include <cstdio> using namespace std; int main() { out<<"Hello world!"; return 0; } Windows: #include <windows.h> int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) { return MessageBox(0,"Hello world!","My first window",0); //1st 0 = HWND_DESKTOP, 2nd 0 = MB_OK } Objektorientierte Varianten Verwendung als Objekt: public class Hallo { void sags(){ System.out.println("Hallo Welt!"); } static void hallo(){ System.out.println("Hallo Welt!"); } public static void main(String[] args) { hallo(); new Hallo().sags(); } } Verwendung als Objekt mit Konstruktor: import java.io.*; public class HalloObj { String bla = "Hallo Welt!"; PrintWriter pw; HalloObj(PrintStream ps){ pw = new PrintWriter(ps,true); } void sags(){ pw.println(bla); } public static void main(String[] args) { (new HalloObj(System.out)).sags(); } } Programmierkurs I (HTML, CSS, Java) - 45 Java, Einleitung 7.3. Software-Entwicklung • Modellierung • Entwurf • Kodierung, Implementierung • Testen • Ausbildung • Anwendung • Wartung Programmieren • Editieren: Schreiben von Programmen in einer bestimmten Programmiersprache • Compilieren: Übersetzen der Programme in "Machinen"code Hinzufügen von anderen Programmteilen (Linken) • Testen: Anwenden des Programms mit Beispieldaten • Programm-Bibliotheken: erlernen, benutzen und aufbauen © Universität Mannheim, Rechenzentrum, 1998-2004. Programmierkurs I (HTML, CSS, Java) - 46 Java, Sprache 8. Java, Sprache 8.1. Sprachaufbau • Lexikalische Elemente • Kommentare • Bezeichner • reservierte Bezeichner und Zeichen • Variablen • Elementare Datentypen • Operatoren • Anweisungen • Kontrollstrukturen • Felder, Arrays Lexikalische Elemente Die elementaren Bestandteile von Java Programmen sind: • White-Space: Leerraum, Tabs • Kommentare • Bezeichner • Schlüsselwörter • Literale • Interpunktionszeichen • Operatoren Kommentare Es gibt drei Arten von Kommentaren in Java: • /* Kommentar */ Für längere Kommentare über mehrere Zeilen, praktisch auch zum vorübergehenden Herauskommentieren von Programmteilen • // Kommentar Ab // werden die Zeichen bis zur nächsten Zeile ignoriert, gebräuchlich für Kommentare innerhalb der Programmzeilen selbst • /** Kommentar */ Kommentar zur Programmdokumentation mit javadoc. Über bestimmte Tags, z.B. • @author text • @version text • @param name Erläuterung • @return Erläuterung lässt sich die Dokumenation sehr übersichtlich gestalten. Programmierkurs I (HTML, CSS, Java) - 47 Java, Sprache Bezeichner Namen von Variablen und Methoden etc. beginnen mit Buchstaben, dürfen "_" und "$" enthalten. reservierte Bezeichner und Zeichen Schlüsselwörter (key words) Eigene Objekte und Variablen kann man beliebig nennen, bis auf folgende, von Java reservierten Worte: abstract double assert ** boolean else break extends byte final case finally catch float char for class goto * const * if continue implements default import do instanceof null true int strictfp ** interface long native new package private protected public return short static false super switch synchronized this throw throws transient try void volatile while * z.Zt unbenutzt, ** neu in Java 2 ( ) { } [ ] = - + * / % < > ! ? & | ~ ; , . Daneben gibt es eine Reihe von Methodennamen mit speziellen Bedeutungen (z.B. main() oder run()). Sie werden in der Regel durch Interfaces vorgeschrieben. Eine Ausnahme ist die Methode main(). Elementare Datentypen In Java sind die primitiven Datentypen architektur-unabhängig definiert. Eine Zusammenstellung befindet sich in Abbildung 1.3. Der Begriff `atomar' wird bei Mulit-threaded Programmen benötigt. Abbildung 1.3: Java-Datentypen Datentyp Inhalt boolean Größe atomar true oder false 1 bit ja char Unicode Zeichen 16 bits ja byte signed integer 8 bits ja short signed integer 16 bits ja int signed integer 32 bits ja long signed integer 64 bits nein float IEEE754 float 32 bits ja double IEEE754 double 64 bits nein String Zeichenkette beliebig nein Zeiger, Pointer null oder Referenz ja Objekt-Referenz Typ Art (Bereich) Programmierkurs I (HTML, CSS, Java) - 48 Java, Sprache ganze Zahlen, Zweierkomplement-Darstellung byte 8-bit Integer mit Vorzeichen (-128 bis 127) short 16-bit Integer mit Vorzeichen (-32.768 bis 32.767) int 32-bit Integer mit Vorzeichen (-2.147.483.648 bis 2.147.483.647) long 64-bit Integer mit Vorzeichen (-9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807) reele Zahlen float 32-bit IEEE 754 Fliesskomma (-3.40282347e+38 bis 3.40282347e+38), 1 Bit Vorzeichen, 8 Bit Exponent, 23 Bit Mantisse double 64-bit IEEE 754 Fliesskomma (-1.7976931348623157e+308 bis 1.7976931348623157e+308) 1 Bit Vorzeichen, 11 Bit Exponent, 52 Bit Mantisse andere Typen char 16-bit Unicode character (65536 Zeichen). boolean Boolscher Wert (wahr oder falsch) Die Größe der Datentypen ist unabhängig vom Rechnersystem und der Java-Implementierung! Zu allen elementaren Datentypen existieren sogenannte Hüllklassen Byte, Short, Integer, Long, Float, Double, Character und Boolean. Beispiel: public // // // class PrimitivTypen { lexikalische Typen sind int und double andere direkte Wertzuweisungen müssen "gecastet" werden z.B.: byte b = (byte)37; short s = (short)37; int i = 37; // dezimal int j = 012; // oktal -> 10 dez int k = 0x14; // hexadezimal -> 20 dez long l = 37L; float f = 0.37F; double d = 0.37; double e = 0.37e+10; char c = 'K'; boolean w = true; } Variablen Abstraktion für Werte, Speicherstelle, Schublade • Name: ein Bezeichner • Typ: ein elementarer Typ oder Klassen-/Objekt-Typ • Wert: Bitmuster im Speicher Programmierkurs I (HTML, CSS, Java) - 49 Java, Sprache • Semantik: Bedeutung des Bitmusters entsprechend dem Typ • Definition durch typ name; bzw. typ name = anfangswert; • Ändern des Wertes durch Zuweisung name = neuerwert • Definition von Konstanten durch final typ NAME = wert; Es gibt unter anderem folgende drei Arten von Variablen: • lokale Variablen: werden lokal innerhalb eines {...}-Blocks (z.B. Methode) definiert und sind nur dort verfügbar. • Objekt-Variablen: werden in Klassen definiert und gehören zum erzeugten Objekt • Klassen-Variablen: werden in Klassen definiert und sind ohne erzeugtes Objekt verwendbar Beispiel: public class Variablen { // Variablen haben // einen Namen, einen Wert und einen Typ int eineVariableVomTypint; int i = 3; // bitmuster: 0...011 long index = 0; Integer x = null; Integer y = new Integer( 3 ); String s = "Eine Zeichenkette"; String w = s + " mit Erweiterung"; java.util.Date d = new java.util.Date(); } Operatoren Zur Verknüpfung von elementaren Datentypen: postfix operators [] . (params) expr++ expr-unary operators ++expr --expr +expr -expr ~ ! creation or cast new (type)expr multiplicative * / % additive + shift << >> >>> relational < > <= >= instanceof equality == != bitwise AND & bitwise exclusive OR ^ bitwise inclusive OR | bitwise NOT ~ logical AND && logical OR || logical NOT ! conditional ? : assignment = += -= *= /= %= &= ^= |= <<= >>= >>>= Beispiel: Programmierkurs I (HTML, CSS, Java) - 50 Java, Sprache public class Operatoren { public void numericalops() { int n = 43; n += 7; // ist eine Abkuerzung von n = n + 7; // dies funktioniert auch mit -, /, >>, etc. n = n * 2; // verdoppelt n n = n / 2; // teilt n ganzzahlig durch 2 n = n % 2; // Rest der ganzzahligen Division } strictfp public void floatingpointops() { double d = 2.71; float one = 1.0f; float f = 1.0f / (float)2; // liefert das float// Divisionsergebnis double zero = 0.0; // 0.0 zero = 1/2; // 0.0 double p = d / zero; double n = -d / zero; // Double.POSITIVE_INFINITY // Double.NEGATIVE_INFINITY double z = zero / zero; // NaN = not a number z = d * zero + p; } public void logicalops() { boolean bool = true && false; bool = true || false; // bool bool = true == false; // bool bool = false != true; // bool // bool ist false ist true ist false ist true bool = !bool; // ! nimmt eine logische Negierung vor // bool ist jetzt gleich false bool = 4 >= 3; // bool ist true bool = 4 != 4; // bool ist false } public void difficultops() { int var = 0; if (var++ < 0); // ist gleichbedeutend mit if (var < 0); var = var + 1; if (--var == 2); // ist gleichbedeutend mit var = var - 1; if ( var == 2 ); int a = 1; int conditional = ( a == 4 ? 3 : -2 ); // conditional ist jetzt -2 } public void bitwiseops() { int i = 3; i = i << 1; // i ist jetzt 6 i = i & 7; // i ist jetzt 6 i = i | 3; // i ist jetzt 7 } } Programmierkurs I (HTML, CSS, Java) - 51 Java, Sprache Anweisungen, Blöcke, Sichtbarkeit Zuweisung, Zusammenfassung von mehreren Anweisungen in Blöcken. Lebensdauer und Sichtbarkeit von Variablen in Blöcken. • Anweisung: Zuweisung, Methodenaufruf, bestimmte Ausdrücke • Zusammenfassung mehrerer Anweisungen in einem Block: { ... } • Variablen, die in einem Block definiert werden, sind nach seinem Verlassen nicht mehr sichtbar • in einem Block dürfen keine Variablen deklariert werden, in einem umgebenden Block schon deklariert sind statement; name = wert; name.methode(); name++; { statement1, ..., statementn; } Beispiel: public class Sichtbarkeit { void anweisung() { int x; x = 3; System.out.println("x = " + x); x++; } void blocks() { int x = 1; int y; { int x = 2; // fehler x wird verdeckt y = x; } y = x; } void leben() { int x = 1; { int y = 2; } x = y; // fehler y existiert nicht mehr } } Kontrollstrukturen Kontrollstrukturen dienen dem Ausführen von Programmteilen in Abhängigkeit von sich ändernden Bedingungen. Statement Keyword decision making loop if-else, switch-case for, while, do-while miscellaneous break, continue, label:, return Schleifen und bedingte Anweisungen Java hat die üblichen auch von C und C++ bekannten while-, do- und for-Schleifen-Konstrukte. Programmierkurs I (HTML, CSS, Java) - 52 Java, Sprache if (condition) { statements } else { statements } for (int i=0; i < end; i++) { statements } while (condition) { statements } do { statements } while (condition); switch (var) { case a: statements; break; case b: statements; break; ... default: statements; } break und continue können analog zu C/C++ in einer Schleife benutzt werden, um die gesamte Schleife zu verlassen, bzw. um die aktuelle Schleife zu beenden. Beispiel: public class Kontrollstrukturen { public void decision() { int variable; variable = 2; if (variable > 1 && variable == 2) { variable = variable - 1; } else { variable = variable + 1; } switch (variable) { case 0: case 1: // variable ist 0 oder 1 break; case 2: variable = variable * 2; break; default: // variable ist nicht 0, 1 oder 2 } } public void loop() { // dreimal die selbe Schleife for (int index = 0; index < 4; index = index + 1) { // tue irgendwas 4 mal } int index = 0; while (index < 4) { index = index + 1; } Programmierkurs I (HTML, CSS, Java) - 53 Java, Sprache index = 0; do { index = index + 1; } while (index < 4); } public void miscellaneous() { int i = 0; while (1 > 0) { i = i + 2; if (i > 5) break; // verlaesst die while-Schleife continue; // faengt sofort wieder am // Schleifen-Kopf an } return; // beendet die Methode sofort } } weitere Beispiele zu Schleifen: for (int i = 0; i < args.length-1; i++ ) { for (int j = i+1; j < args.length; j++) { if ( args[i].equals( args[j] ) ) { ... } } } for ( Iterator it = verschiedeneArgs.keySet().iterator(); it.hasNext(); /* fehlt */ ) { Object arg = it.next(); ... } Iterator it = verschiedeneArgs.keySet().iterator(); while ( it.hasNext() ) { Object arg = it.next(); ... } Java Syntax aus der Sprachdefinition. Felder, Arrays, Reihungen Ein Array, d.h. einen Vektor oder eine Matrix, kann man ebenfalls durch new erzeugen. byte[] buffer = new byte[4096]; byte[] data = new byte[4096]; int[][] plot = new int[64][64]; ... Date[] ds = new Date[16]; Auf die Elemente eines Arrays kann über ihren Index zugegriffen werden. for (int i=0; i < buffer.length; i++) buffer[i] = data[i]; In der length Variablen eines Array Objekts steht die Information über die Länge bereit. Bemerkung: Java erlaubt (aus Gründen der Kompatibilität zu C/C++) auch die Notation byte buffer[] = new byte[4096]. Wir werden davon aber keinen Gebrauch machen. Beispiel: Programmierkurs I (HTML, CSS, Java) - 54 Java, Sprache import java.util.Date; public class Reihungen { byte[] buffer = new byte[4096]; byte[] data = new byte[4096]; int[][] plot = new int[64][64]; float[] stat = { 1.0f, 2.0f, 3.14f, 2.71f, 1.99f }; Date[] ds = new Date[16]; public void initialisieren() { for (int i=0; i < buffer.length; i++) buffer[i] = (byte)i; for (int i=0; i < ds.length; i++) { ds[i] = new Date(); } } public void kopieren() { for (int i=0; i < buffer.length; i++) data[i] = buffer[i]; } public int summieren() { int sum = 0; for (int i=0; i < buffer.length; i++) { sum += buffer[i]; } return sum; } } © Universität Mannheim, Rechenzentrum, 2000-2004. Last modified: Sun Oct 24 13:31:57 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 55 Java, Klassen 9. Java, Klassen 9.1. Klassen und Objekte • Unterprogramme, Methoden • Klassen und Objekte • Parameterübergabe von Referenzen • Kapselung und Zugriffskontrolle • Konstruktoren • Datentyp Complex Unterprogramme, Methoden Unterprogramme sind Prozeduren und Funktionen, in Java werden sie als Methoden bezeichnet. • Unterprogramme bestehen aus einem Kopf (head) und einem Rumpf (body) • der Rumpf ist eine Zusammenfassung von Anweisungen • in dem Kopf wird der Name des Unterprogramms definiert, sowie die Parameter und der Ergebnistyp • bei Prozeduren ist der Ergebnistyp void • die Parameter (als formale Parameter bezeichnet) definieren im Rumpf lokale Variablen • Aufruf einer Methode erfolgt durch Angabe des Namens, gefolgt von den aktuellen Parametern (getrennt durch Komma) in Klammern name( p1, p2, f(p3), p4+5 ) • Signatur, Aufrufschnittstelle: Anzahl und Typen der Parameter sowie des Ergebnistyps (void, int, String[], Integer) • Überladen: Methoden mit gleichem Namen, die sich in der Signatur unterschieden (in Java nur der formalen Parameter), bei der Auswahl muss die Eindeutigkeit gewährleistet werden (int, String[], Integer), (double, String[], Double) • Parameterübergabe: Wertaufruf (call by value): der berechnete Wert der Ausdrucks wird verwendet (in Java für elementare Typen und Objektreferenzen) Referenzaufruf (call by reference): nur bei Variablen als Parameter, Ermöglicht Zuweisungen an die Variable im Rumpf (nicht in Java, aber Objekte sind Referenzen) Namensaufruf (call by name): textuelle Substitution wie bei LISP/Scheme (nicht in Java) • die Prozedur public static void main(String[] args) { } wird vom Java-Interpreter als erste ausgeführt • bei rekursiven Prozeduren wird im Rumpf die Prozedur selbst wieder aufgerufen, void prozedur( parameter ) block; typ funktion( parameter ) { ... return (typ) wert; ... } typ methode( ... int x = int y = int z = ... typ_1 name_1, ..., typ_n name_n ) { (int)name_1; funktion( name_2, 4711 ); name_3 + name_n; Programmierkurs I (HTML, CSS, Java) - 56 Java, Klassen } public static void main(String[] args) { // die Hauptprozedur, // d.h. die erste die ausgeführt wird } Beispiele: public class Unterprogramme { void prozedur() { } int funktion() { return 4711; } int quadrat(int a) { return a*a; } double quadrat(double a) { return a*a; } int name(int a) { int b = quadrat( 2 ); return b+a; } long fakultaet(long n) { if ( n <= 1l ) { return 1l; } else { return n * fakultaet( n-1l); } } double summe(double[] a) { double sum = 0.0; for ( int i = 0; i < a.length; i++ ) { sum += a[i]; } return sum; } void main() { prozedur(); int n = funktion(); int i = quadrat(n); int j = name( 3 ); long k = fakultaet( 10 ); double[] z = { 1.0, 1.2, 3.2, 4.6, 9.2 }; double s = summe( z ); System.out.println("n System.out.println("i System.out.println("j System.out.println("k System.out.println("s = = = = = " " " " " + + + + + n); i); j); k); s); } public static void main(String[] args) { // die Hauptprozedur, (new Unterprogramme()).main(); } } public class Ueberladen { Programmierkurs I (HTML, CSS, Java) - 57 Java, Klassen void problem(int a, long b) { } void problem(long a, long b) { } void problem(long a, int b) { } void ratemal() { problem( 1, 2L ); // ok problem( 1L, 2 ); // ok problem( 1, 2 ); // fehler } long problem(long a, long b) { // fehler return a*b; } } public class Uebergabe { class Unter { int a = 0; int b = 1; } void wert( int c ) { c = c + 55; } void referenz( Unter u ) { int x = u.a * 3; u.b = x + 14; } void unveraendert( Unter u ) { u = new Unter(); int x = u.a * 3; u.b = x + 14; } void ratemal() { int w = 3; wert( w ); // w == 3 Unter u = referenz( // u.a == // u.b == new Unter(); u ); 0 14 unveraendert( u ); // u.a == 0 // u.b == 1 } } public class Rekursion { long fakultaet(int n) { if ( n <= 1 ) { return 1l; } else { return n * fakultaet( n-1); } } double summe(double[] a) { double sum = 0.0; for ( int i = 0; i < a.length; i++ ) { Programmierkurs I (HTML, CSS, Java) - 58 Java, Klassen sum += a[i]; } return sum; } double reksumme(double[] a) { return reksumme(a,a.length); } double reksumme(double[] a, int n) { if ( n == 0 ) return 0.0; return reksumme(a,n-1) + a[n-1]; } long potenz(int b, int e) { // berechne b hoch e // if ( e < 0 ) { b = 1/b; e = -e; } if ( e == 0 ) return 1l; if ( e == 1 ) return (long)b; return b * potenz( b, e-1 ); } long quadrat(long b) { // berechne b*b return b*b; } long potenzFast(int b, int e) { // berechne b hoch e // if ( e < 0 ) { b = 1/b; e = -e; } if ( e == 0 ) return 1l; if ( e == 1 ) return (long)b; if ( e % 2 == 0 ) return quadrat( potenzFast( b, e/2 ) ); return b * potenzFast( b, e-1 ); } void main() long k = double[] double s double r long p = long f = { fakultaet( 10 ); z = { 1.0, 1.2, 3.2, 4.6, 9.2 }; = summe( z ); = reksumme( z ); potenz( 10, 15 ); potenzFast( 10, 15 ); System.out.println("k System.out.println("s System.out.println("r System.out.println("p System.out.println("f = = = = = " " " " " + + + + + k); s); r); p); f); } public static void main(String[] args) { // die Hauptprozedur, (new Rekursion()).main(); } } public class Summe { static double[] betrag = null; static double summe() { double s = 0.0; for (int i = 0; i < betrag.length; i++ ) { s += betrag[i]; } return s; } public static void main(String[] args) { betrag = new double[args.length]; for (int i = 0; i < args.length; i++) { Programmierkurs I (HTML, CSS, Java) - 59 Java, Klassen betrag[i] = 0.0; try { betrag[i] = Double.parseDouble( args[i] ); // betrag[i] = Double.valueOf( args[i] ).doubleValue(); } catch (NumberFormatException e) { } } System.out.println("Eingegeben wurden " + args.length + " Zahlen"); double s = summe(); System.out.println("Die Summe ist " + s); } } Java Syntax aus der Sprachdefinition. Klassen und Objekte Klassen bieten die Zusammenfassung von Funktionen, Prozeduren und Variablen zu einem bestimmten Zweck. (Abstraktion von einzelnen Methoden zu Modulen oder Gruppen.) • Klassen sind zusammengesetzte Datentypen. • die Klassendeklaration definiert die Bestandteile: • Variablen, Datenfelder (Attribute, fields) • Methoden (methods) • Konstruktoren (Initialisierer) • Ein Objekt ist ein Exemplar einer Klasse (auch als Instanz bezeichnet) • Ein Objekt einer Klasse kann durch das Schlüsselwort new erzeugt werden. • ein Objekt enthält die Bestandteile: • Instanz-Variablen • Klassen-Variablen (static) • Instanz-Methoden • Klassen-Methoden (static) • Der Zugriff auf Objektbestandteile erfolgt mit dem Punktoperator '.' • Variablen einer Klasse deklariert man durch den Namen der Klasse, gefolgt vom Namen der Variablen Klasse var (entspricht Klasse var = null). Der Variablen muss anschliessend ein (neues) Objekt zugewiesen werden. • Konstruktoren sind spezielle Methoden mit dem Namen der Klasse ohne Rückgabeparameter. Bei der Erzeugung eines neuen Objekts wird entsprechend der aktuellen Parameter ein passender Konstruktor ausgewählt, der die Instanz-Variablen initialisieren kann. Diagramme für Klassen in der Unified Modeling Language (UML): Name Zustand, Attribute Funktionalität, Methoden public class Klassen { static int klassen = 0; int meineNummer = 0; Klassen() { meineNummer = klassen++; } Programmierkurs I (HTML, CSS, Java) - 60 Java, Klassen static String statistik() { return "Erzeugte Objekte = " + klassen; } public String toString() { return "Meine Nummer = " + meineNummer + " von " + klassen; } public static void main(String[] args) { System.out.println( Klassen.statistik() ); Klassen einz = new Klassen(); Klassen zwei = new Klassen(); Klassen drei = new Klassen(); Klassen vier = new Klassen(); Klassen fuenf = new Klassen(); System.out.println( statistik() ); System.out.println("einz: " + einz.toString()); System.out.println("zwei: " + zwei); System.out.println("vier: " + vier); System.out.println("drei: " + drei); System.out.println("fuenf: " + fuenf); } } Klassen UML Diagramm Java-Programme werden mittels Klassen definiert. Jede öffentliche (d.h. als public deklarierte) Klasse muß in einer separaten Datei gespeichert werden. Der Name der Datei muß mit dem Namen der public-Klasse übereinstimmen (z.B. muß die Klasse public class Test in der Datei Test.java gespeichert werden). Der Speicherbereich für das Objekt wird automatisch allokiert. Wenn das Objekt nicht mehr gebraucht wird (d.h. keine Variable referenziert mehr das Objekt), wird der Speicherbereich während eines Garbage-Collection-Vorganges wieder freigegeben (Speicherrecycling). Das heißt, daß im Gegensatz zu C/C++ kein expliziter `delete'-Operator benötigt wird. In Java können Prozeduren nur innerhalb von Klassen definiert werden. Prozeduren können zu einer Klasse oder zu Objekten gehören. Es gibt in Java keine freien / globalen Variablen oder Methoden. public class Card { int number; static int base = 5; public static String version = "1.0"; public Card(int n) { number = n; } Programmierkurs I (HTML, CSS, Java) - 61 Java, Klassen public int getNumber() { return number; } public static int getBase() { return base; } public int getDiff() { return number - base; } public static void main(String[] args) { Card c = new Card(7); System.out.println(c.version+":"+ c.getNumber()+"-"+c.getDiff()+"="+ Card.getBase()); } } Die Ausgabe dieses Programms ist 1.0:7-2=5. Card UML Diagramm Parameterübergabe von Objektreferenzen Die Übergabe von Objektrefrenzen ermöglicht die Veränderung von übergebenen Objekten in der aufrufenden Methode. public class Confuse { static class Reference { int val; } public int confuse( int a, int b ) { a = 1; a = b + a; Programmierkurs I (HTML, CSS, Java) - 62 Java, Klassen return a; } public Integer confuse( Integer a, Integer b ) { a = new Integer(1); a = new Integer( b.intValue() + a.intValue() ); return a; } public Reference confuse( Reference a, Reference b ) { a.val = 1; a.val = b.val + a.val; return a; } public static void main(String[] args) { Confuse c = new Confuse(); int m = 4; int n = c.confuse( m, m ); System.out.println("m = " + m); System.out.println("n = " + n); Integer i = new Integer(4); Integer j = c.confuse( i, i ); System.out.println("i = " + i); System.out.println("j = " + j); Reference k = new Reference(); k.val = 4; Reference l = c.confuse( k, k ); System.out.println("k = " + k.val ); System.out.println("l = " + l.val ); } } Confuse UML Diagramm Das Problem kann durch Zugriffskontrolle gelöst oder beherscht werden. Kapselung und Zugriffskontrolle Klassen bzw. Objekte können ihre Variablen und Methoden in verschiedenen Abstufungen kapseln (einschliessen). Dabei werden Programmierkurs I (HTML, CSS, Java) - 63 Java, Klassen nur die Variablen oder Methoden nach aussen, d.h. für andere Objekte sichtbar gemacht, die notwendig sind. Man spricht auch vom Geheimnisprinzip. Die öffentlich zugänglichen Variablen und Methoden werden meist noch durch Interfaces (s.u.) definiert. Vorteil: die Interna können beliebig modifiziert werden solange die Schnittstelle und deren Semantik erhalten bleibt. Java unterschiedet public, private, protected und default Zugriffsrechte. • public völlig öffentlich • private nur in Objekten der eigenen Klasse sichtbar • protected in Objekten der Klassenhierarchie sichtbar, d.h. in abgeleiteten Klassen • nichts, d.h. default: nur im gleichen Package sichtbar Beispiele siehe Abschnitt "Sichtbarkeit". Der Kontrakt zwischen dem/der Entwicklerin einer Klasse und einem Anwender besteht aus der Syntax und Semantik der Aufrufschnittstelle. Konstruktoren Konstruktoren dienen der Initialisierung der Objekt-Variablen. Klassen-Variablen werden ein einziges mal vor der ersten Verwendung der Klasse initialisiert. • der Name der Konstruktoren muss der Name der Klasse sein • Konstruktoren sehen aus wie Methoden ohne Rückgabetyp Definition • Konstruktoren können wie Methoden überladen werden • für Konstruktoren gelten die üblichen Zugriffsspezifikationen • Konstruktoren der Superklasse können explizit mit super(...) verwendet werden • andere Konstruktoren der eigenen Klasse können explizit mit this(...) verwendet werden Beispiel für einen neuen Datentyp Wir entwickeln eine Klasse Complex, die für die Arithmetik komplexer Zahlen verwendet werden kann. Der Konstruktor soll aus einem Paar reeler Zahlen (a,b) eine komplexe Zahl a + i b machen. Methoden und Konstanten: • Null ist 0 + i 0 , Einz ist 1 + i 0, • Feststellen des Real- und Imaginär-Teils, • Anzeige mit toString() von Object, • Test auf Gleichheit, • Addition: (a + i b) + (c + i d) = (a+c) + i (b+d), • Subtraktion analog, negative Zahl, • Multiplikation: (a + i b) * (c + i d) = (ac-bd) + i (ad+bc), • Konjugation: con(a + i b) = a - i b, • Betrag: abs(a + i b) = sqrt( a a + b b ), • Inverses: inv(a + i b) = con(a + i b)/abs(a + i b), • Division: (a + i b) / (c + i d) = (a + i b) * inv(c + i d), Programmierkurs I (HTML, CSS, Java) - 64 Java, Klassen Programmierkurs I (HTML, CSS, Java) - 65 Java, Klassen Complex UML Diagramm /** * Klasse zum Rechnen mit Komplexen Zahlen * hk, 9.12.2001 * **/ public class Complex { /* Die Datenstruktur */ private double re; private double im; // der Realteil // der Imaginärteil /* Die Konstruktoren erzeugen aus einem Paar von double Zahlen eine Komplexe Zahl */ public Complex(double r, double i) { re = r; im = i; } public Complex(double r) { this(r,0.0); } public Complex() { this(0.0); } /* Konstanten: 1, 0 und i */ public static final Complex ZERO = new Complex(); public static final Complex ONE = new Complex(1.0); public static final Complex I = new Complex(0.0,1.0); /* Bestimmen des Real- und Imaginär-Teils */ public double reTeil() { return re; } public double imTeil() { return im; } /* Darstellung als Zeichenkette */ public String toString() { String s = "" + re; if ( im < 0 ) s += " - " + (-im) + "i"; else s += " + " + im + "i"; return s; } /* Vergleich zweier Komplexer Zahlen */ public boolean equals(Complex b) { return ( re == b.reTeil() && im == b.imTeil() ); } /* Arithmetische Operationen: +, -, - */ public Complex add(Complex b) { return new Complex(re + b.reTeil(), im + b.imTeil()); } Programmierkurs I (HTML, CSS, Java) - 66 Java, Klassen public Complex subtract(Complex b) { return new Complex(re - b.reTeil(), im - b.imTeil()); } public Complex negate() { return new Complex(-re,-im); } /* Arithmetische Operationen: Konjugierte, Absolut Betrag */ public Complex conjugate() { return new Complex(re,-im); } public double abs() { return ( Math.sqrt( re * re + im * im ) ); } /* Arithmetische Operationen: *, Inverse, / */ public Complex multiply(Complex b) { return new Complex(re * b.reTeil() - im * b.imTeil(), re * b.imTeil() + im * b.reTeil() ); } public Complex inverse() { double a = re * re + im * im; return new Complex(re/a, -im/a); // Konjugierte } public Complex divide (Complex b) { return this.multiply( b.inverse() ); } } Anwendungsbeispiel /** * Testen der Klasse zum Rechnen mit Komplexen Zahlen * hk, 9.12.2001 * **/ public class ComplexTest { public static void main(String[] args) { Complex a = new Complex(2.0,3.0); System.out.println("a(2,3) = " + a); System.out.println("Null(0,0) = " + Complex.ZERO); System.out.println("Eins(1,0) = " + Complex.ONE); Complex b = Complex.ONE; b = b.add(a); System.out.println("b(3,3) = " + b); Complex c = new Complex(3.0,3.0); System.out.println("c(3,3) = " + c); boolean t = c.equals(b); System.out.println("t(true) = " + t); Complex d = c.conjugate(); System.out.println("d(3,-3) = " + d); double e = c.abs(); System.out.println("e(18) = " + e); Complex f = c.multiply(d); Programmierkurs I (HTML, CSS, Java) - 67 Java, Klassen System.out.println("f(18,0) = " + f); // c*conjugate(c) = abs(c)^2 t = e == Math.sqrt( f.reTeil() ); System.out.println("t(true) = " + t); // i*i = -1 Complex g = Complex.I.multiply(Complex.I); System.out.println("g(-1,0) = " + g); // 1/i = -i Complex h = Complex.ONE.divide(Complex.I); System.out.println("h(0,-i) = " + h); } } © Universität Mannheim, Rechenzentrum, 1998-2004. Programmierkurs I (HTML, CSS, Java) - 68 Java, Vererbung 10. Java, Vererbung 10.1. Vererbung und Interfaces • Vererbung • Überschreiben • Typanpassungen • Interfaces • abstrakte Klassen Vererbung Mit den Konzepten der Vererbung (inheritance) kommen wir zu höheren objektorientierten Konzepten. • Modellierung einer "ist-ein"-Beziehung zwischen Datentypen • manchmal ist ein Datentyp A ein Untertyp eines Obertyps B • die Klasse A ist dann eine Erweiterung der Klasse B, d.h. alles was B hat hat auch A • um die Implementierung von B bei der Implementierung von A wiederzuverwenden (re-use) verwendet man in Java die Vererbung mit class A extends B • B ist die sogenannte Basisklasse und A ist die abgeleitete Klasse, man sagt auch A ist eine Unterklasse (sub-class) und B ist die Oberklasse (super class) • alle Methoden von B sind somit in A und über A-Objekte verwendbar • A kann Methoden von B durch eigene (passendere) Methoden mit der gleichen Signatur überschreiben • von einer Klasse B können beliebig viele Klassen abgeleitet werden • eine Klasse A kann nur von einer Klasse erben (single inheritance) • in einem Konstruktor von A wird implizit der argumentlose Konstruktor von B aufgerufen super() • andere Konstruktoren können explizit mit super(...) (als erste Anweisung) angesprochen werden • alle Klassen erben implizit von Object • durch endgültige Klassen (final class) lässt sich die Vererbung / Ableitung verhindern Programmierkurs I (HTML, CSS, Java) - 69 Java, Vererbung Vererbung UML Diagramm public class Vererbung { public static void main(String[] args) { B1 b = new B1(); System.out.println("b = " + b); B1.method(); b.objmethod(); A1 a = new A1(); System.out.println("a = " + a); a.objmethod(); a.andere(); b = a; System.out.println("b = " + b); b.objmethod(); //b.andere(); // Fehler Programmierkurs I (HTML, CSS, Java) - 70 Java, Vererbung C1 c = new C1(); System.out.println("c = " + c); C1.method(); c.objmethod(); D1 d = new D1(); System.out.println("d = " + d); d.andere(); b = c; System.out.println("b = " + b); b = d; System.out.println("b = " + b); } } class B1 { static void method() { } void objmethod() { } public String toString() { return "ich bin ein B1"; } } class A1 extends B1 { void andere() { } public String toString() { return "ich bin ein A1"; } } class C1 extends B1 { public String toString() { return "ich bin ein C1"; } } class D1 extends A1 { public String toString() { return "ich bin ein D1"; } } Überschreiben Eine Methode in A implementiert eine Methode mit gleicher Schnittstelle von B, aber mit anderer Bedeutung (Semantik) (overriding). Auch virtuelle Vererbung und virtuelle Methoden genannt im Gegensatz zu realer Vererbung (oben). es gelte class A extends B { ... } • gleiche Schnittstelle: d.h. gleiche Signatur (Name, Anzahl und Typ der Parameter) • das reale Objekt entscheidet über die Bedeutung der Methode, nicht der Typ der Objektvaraiblen • die Auswahl der realen Methode erfolgt erst zur Laufzeit, nicht bei der Kompilierung (dynamische Bindung, dynamic/late binding) Programmierkurs I (HTML, CSS, Java) - 71 Java, Vererbung • z.B. toString() konvertiert immer das reale Objekt in eine Zeichenkette • das Überschreiben lässt sich durch endgültige Methoden (final) verhindern, ?? Klassenmethoden (static) lassen sich nicht Überschreiben ?? • durch das Ableiten einer Klasse wird implizit das Versprechen abgegeben (Kontrakt vereinbart), dass sich Objekte, die auf die Basisklasse reduziert werden genau so verhalten wie Objekte der Basisklasse Ueberschreiben UML Diagramm public class Ueberschreiben { public static void main(String[] args) { B2 b = new B2(); System.out.println("b = " + b); B2.method(); System.out.println("b.objmethod() = " + b.objmethod()); A2 a = new A2(); System.out.println("a = " + a); System.out.println("a.objmethod() = " + a.objmethod()); b = a; System.out.println("b = " + b); System.out.println("b.objmethod() = " + b.objmethod()); } Programmierkurs I (HTML, CSS, Java) - 72 Java, Vererbung } class B2 { static void method() { } String objmethod() { return "von B2"; } public String toString() { return "ich bin ein B2"; } } class A2 extends B2 { static void method() { } String objmethod() { return "von A2"; } void andere() { } public String toString() { return "ich bin ein A2"; } } Typanpassungen es gelte wieder class A extends B { ... } • Ausweitung (widening): von der abgeleiteten Klasse zur Basisklasse B b = new A(), auch Aufwärtsanpassung genannt • Verengung (narrowing): von der Basisklasse zu einer abgeleiteten Klasse A a = (A) b nur mit explizitem Typecast, auch Abwärtsanpassung genannt • falls die Verengung nicht möglich ist wird eine ClassCastException ausgelöst • mit Hilfe von instanceof lässt sich testen ob ein Objekt zu einer bestimmten (abgeleiteten) Klasse gehört, if (b instanceof A) ((A) b).method(); Programmierkurs I (HTML, CSS, Java) - 73 Java, Vererbung Anpassung UML Diagramm public class Anpassung { public static void main(String[] args) { B3 b = new B3(); System.out.println("b = " + b); A3 a = new A3(); System.out.println("a = " + a); b = a; System.out.println("b = " + b); if (b instanceof A3) a = (A3) b; System.out.println("a = " + a); ((A3) b).andere(); } } class B3 { void objmethod() { } public String toString() { return "ich bin ein B3"; } } class A3 extends B3 { Programmierkurs I (HTML, CSS, Java) - 74 Java, Vererbung void andere() { } public String toString() { return "ich bin ein A3"; } } Beispiel Autos Wir definieren eine einfache Klasse für Autos (Car). Man kann mit dieser Klasse ein Auto mit den Parametern Modell (model), Baujahr (year) und (Neu-)Preis (price) definieren. Cars UML Diagramm Die Klassen-Methoden getModel(), getYear() und getPrice() dienen dem Zugriff auf die Objekt-Variablen. Programmierkurs I (HTML, CSS, Java) - 75 Java, Vererbung public class Car { String model; int year; int price; public Car(String m, int y, int p) { model = m; year = y; price = p; } public String getName() { return model+" [year="+year+"]"; } public int getPrice() { return price; } public static void main(String[] args) { Car ford = new Car("ford bronco", 1992, 35000); Car vw = new Car("vw golf", 1984, 25000); System.out.println( ford.getName()+" costs "+ford.getPrice()); System.out.println( vw.getName()+" costs "+vw.getPrice()); } } Mit dieser Klasse kann man zum Beispiel die Objekte ford und vw erzeugen. Dies ergibt dann folgende Ausgabe. ford bronco [year=1992] costs 35000 vw golf [year=1984] costs 25000 Mit dem Schlüsselwort extends kann man eine Klasse von einer anderen Klasse ableiten. Als Beispiel einer abgeleiteten Klasse von Car sei die Klasse Gebrauchtwagen (UsedCar) definiert, die den zusätzlichen Parameter `gefahrene Kilometer' (mileage) hat. public class UsedCar extends Car { int mileage; public UsedCar(String m, int y, int p, int k) { super(m, y, p); mileage = k; } public String getName() { return super.getName()+" (mileage="+mileage+")"; } public int getMileage() { return mileage; } public int getPrice() { return 10000*price/(mileage+10000); } } Die Methode getMilage() dient wieder dem Zugriff auf die Klassen-Parameter. Der Konstruktor für UsedCar ruft mit super(m, y, p) den Konstruktor der Basisklasse auf, dann wird der Parameter mileage gesetzt. Die Methode getPrice() überschreibt die Methode mit dem gleichen Namen und der gleichen Signatur (d.h. der gleichen Art und Anzahl der Parameter) von der Basisklasse. getPrice() berechnet in dieser Klasse den Gebrauchtwagenpreis in Abhängigkeit von der gefahrenen Kilometerzahl. Mit diesen Klassen kann man dann zum Beispiel in dem Hauptprogramm main die folgenden Beziehungen definieren und ausdrucken. Programmierkurs I (HTML, CSS, Java) - 76 Java, Vererbung public static void main(String[] args) { Car cars[] = new Car[4]; cars[0] = new Car("ford bronco", 1992, 35000); cars[1] = new UsedCar("ford bronco", 1992, 35000, 8000); cars[2] = new Car("vw golf", 1984, 25000); cars[3] = new UsedCar("vw golf", 1984, 25000, 20000); for (int i=0; i<4; i++) System.out.println(cars[i].getName() +" costs "+cars[i].getPrice()); } Als Ausgabe erhält man zum Beispiel. java UsedCar ford bronco [year=1992] costs 35000 ford bronco [year=1992] (mileage=8000) costs 19444 vw golf [year=1984] costs 25000 vw golf [year=1984] (mileage=20000) costs 8333 Interface Eine Java-Klasse ist nur von einer anderen Klasse ableitbar. Java kennt keine Mehrfachvererbung (multiple inheritance). Aber mit dem Sprachkonstrukt interface kann eine Klasse mehrere Methodensignaturen implementieren (erben). Ein Interface deklariert nur abstrakte Methoden. Zum Beispiel kann man ein Interface Rank definieren, das das Vergleichen zweier Objekte erlaubt. compare() gibt eine positive ganze Zahl zurück, falls dieses Objekt (this) in der implementierten Ordnung vor dem anderen Objekt (obj) steht. Programmierkurs I (HTML, CSS, Java) - 77 Java, Vererbung Ranks UML Diagramm public interface Rank { public int compare(Rank obj) throws RankException; } Ist die implementierte Ordnung nicht total, so wird für unvergleichbare Objekte eine RankException ausgelöst. public class RankException extends RuntimeException { } Eine Subklasse von Rectangle (aus java.awt), die dieses Interface unterstützt, kann man wie folgt definieren. public class RankedRect extends Rect implements Rank { public RankedRect(int w, int h) { super(w,h); } Programmierkurs I (HTML, CSS, Java) - 78 Java, Vererbung public int compare(Rank obj) throws RankException { try { return area() - ((Rect)obj).area(); } catch (ClassCastException e) { throw new RankException(); } } } In einer ähnlichen Weise kann man eine Subklasse von Car definieren. public class RankedCar extends Car implements Rank { public RankedCar(String m, int y, int p) { super(m,y,p); } public int compare(Rank obj) { try { return getPrice()-((Car)obj).getPrice(); } catch (ClassCastException e) { throw new RankException(); } } } Diese beiden Klassen können behandelt werden, als ob sie vom Typ Rank wären. Zum Beispiel als Argument in einer Methode foo(Rank obj). Eine Klasse kann mehrere Interfaces implementieren. Bei der Erzeugung von Objekten von Klassen, die ein Interface implementieren, kann man die Struktur, die nicht von dem Interface stammt, ignorieren. Rank r = new RankedCar(model, year, price); Dann ist aber nur noch die Verwendung der Methode r.compare(.) möglich und nicht mehr r.getModel(). Um dennoch getModel() zu verwenden, muß erst ein Cast (eine Typenanpassung) auf RankedCar gemacht werden: ( (RankedCar) r ).getModel() Abstrakte Klassen Man kann eine Klasse definieren, die keine vollständige Implementierung der deklarierten Methoden enthält. Diese kann man sich als Mischform zwischen einem Interface und einer richtigen Klasse vorstellen. Ein Teil der Methoden wird implementiert, und für einen anderen Teil der Methoden werden nur die Spezifikationen (das Interface) festgelegt. Cell UML Diagramm Eine solche Klasse wird als abstrakte Klasse bezeichnet und muß mit dem Schlüsselwort abstract gekennzeichnet werden. public abstract class Cell { Programmierkurs I (HTML, CSS, Java) - 79 Java, Vererbung int size; public int getSize() { return size; } public abstract void interact(Cell neighbor); } Aus abstrakten Klassen können können keine Objekte erzeugt werden. Aus einer Subklasse, die die fehlenden Implementationen definiert, können Objekte erzeugt werden. Beispiel: BitString Programmierkurs I (HTML, CSS, Java) - 80 Java, Vererbung Programmierkurs I (HTML, CSS, Java) - 81 Java, Vererbung BitString UML Diagramm Interface: BitStringInterface Methoden: toString() und toBitString() liefern die entsprechende Darstellung als Binärfolge. public interface BitStringInterface { public String toString(); public String toBitString(); } Abstrakte Klasse: AbstractBitString Methoden: toString() wird mit Hilfe von toBitString() implementiert. public abstract class AbstractBitString implements BitStringInterface { protected int art; final static int BYTE final static int SHORT final static int INT final static int LONG final final final final static static static static byte byte byte byte = = = = 1; 2; 3; 4; BYTEsize SHORTsize INTsize LONGsize = 7; = 15; = 31; = 63; protected long ls = 0; public String toString() { return toBitString(); } public abstract String toBitString(); } Klasse: BitStringSign Darstellung von ganzen Zahlen als Binärfolge. Die Zahlen werden als Paare von Vorzeichen und positiven Zahlen dargestellt. Konstruktoren: für byte, short, int und long, Methoden: toBitString() liefert Zeichenkette entsprechend dem Datentyp. bitStringSign() liefert Zeichenkette entsprechend der 'Vorzeichen, Grösse'-Darstellung. public class BitStringSign extends AbstractBitString { public BitStringSign(byte b) { art = BYTE; ls = b; } public BitStringSign(short s) { art = SHORT; ls = s; } public BitStringSign(int s) { art = INT; ls = s; } Programmierkurs I (HTML, CSS, Java) - 82 Java, Vererbung public BitStringSign(long s) { art = LONG; ls = s; } public String toBitString() { switch (art) { case BYTE: return bitStringSign(BYTEsize,ls); case SHORT: return bitStringSign(SHORTsize,ls); case INT: return bitStringSign(INTsize,ls); case LONG: return bitStringSign(LONGsize,ls); default: return ""+ls; } } protected static String bitStringSign(byte l, long b) { String e = ""; long x = 0; String s = ""; byte einz = (byte)1; if (b < 0L ) { x = (long)-b; s = "1"; } else { x = (long)b; s = "0"; } for (int i = 0; i < l; i++) { // (x % 2) == 0 if ( ( ((byte)x) & einz) == 0 ) { e = "0" + e; } else { e = "1" + e; } x = (long)(x >> 1); } return s+e; } } Klasse: BitStringComplement Darstellung von ganzen Zahlen als Binärfolge. Die Zahlen werden im Zweier-Komplement dargestellt. Konstruktoren: für byte, short, int und long, Methoden: toBitString() liefert Zeichenkette entsprechend dem Datentyp. bitStringComplement() liefert Zeichenkette entsprechend der Komplement-Darstellung. public class BitStringComplement extends AbstractBitString { public BitStringComplement(byte b) { art = BYTE; ls = b; } public BitStringComplement(short s) { art = SHORT; ls = s; } public BitStringComplement(int s) { art = INT; ls = s; } public BitStringComplement(long s) { art = LONG; ls = s; } Programmierkurs I (HTML, CSS, Java) - 83 Java, Vererbung public String toBitString() { switch (art) { case BYTE: return bitStringComplement(BYTEsize,ls); case SHORT: return bitStringComplement(SHORTsize,ls); case INT: return bitStringComplement(INTsize,ls); case LONG: return bitStringComplement(LONGsize,ls); default: return ""+ls; } } protected static String bitStringComplement(byte l, long b) { String e = ""; long x = b; byte einz = (byte)1; for (int i = 0; i < l+1; i++) { // (x % 2) == 0 if ( ( ((byte)x) & einz) == 0 ) { e = "0" + e; } else { e = "1" + e; } x = (long)(x >> 1); } return e; } } Klasse: BitTest Testen der zwei Darstellungen. Es werden Objekte von BitStringSign und BitStringComplement erzeugt. Diese Objekte können in Variablen der entsprechenden Klassen abgespeichert werden, aber auch in Variablen vom Typ BitStringInterface als auch von Typ AbstractBitString. public class BitTest { public static void main(String[] args) { test1(); test2(); test3(); test4(); } static void test1() { BitStringInterface a = new BitStringSign((int)7); System.out.println("sign( 7) = " + a); BitStringInterface b = new BitStringComplement((int)7); System.out.println("cmpl( 7) = " + b); BitStringInterface g = new BitStringSign((int)-7); System.out.println("sign( -7) = " + g); BitStringInterface h = new BitStringComplement((int)-7); System.out.println("cmpl( -7) = " + h); BitStringInterface d = new BitStringSign((short)32767); System.out.println("sign( 32767) = " + d); BitStringInterface c = new BitStringComplement((short)32767); System.out.println("cmpl( 32767) = " + c); AbstractBitString e = new BitStringSign((int)-32767); System.out.println("sign(-32767) = " + e); AbstractBitString f = new BitStringComplement((int)-32767); System.out.println("cmpl(-32767) = " + f); System.out.println(); } static void test2() { Programmierkurs I (HTML, CSS, Java) - 84 Java, Vererbung short x = -1; for (byte l = 0; l <= 15; l++ ) { BitStringInterface g = new BitStringSign((short)x); System.out.println("sign( "+ x + ") = " + g); x *= (short)2; } System.out.println(); } static void test3() { short x = -1; for (byte l = 0; l <= 15; l++ ) { AbstractBitString h = new BitStringComplement((short)x); System.out.println("cmpl( "+ x + ") = " + h); x *= (short)2; } System.out.println(); } static void test4() { short x = -1; for (byte l = 0; l <= 15; l++ ) { System.out.println("Integer( "+ x + ") = " + Integer.toBinaryString(x)); x *= (short)2; } System.out.println(); } } Im letzten Test erfolgt ein Vergleich mit der 'eingebauten' Funktion Integer.toBinaryString(x)) Ausgabe: sign( 7) cmpl( 7) sign( -7) cmpl( -7) sign( 32767) cmpl( 32767) sign(-32767) cmpl(-32767) = = = = = = = = 00000000000000000000000000000111 00000000000000000000000000000111 10000000000000000000000000000111 11111111111111111111111111111001 0111111111111111 0111111111111111 10000000000000000111111111111111 11111111111111111000000000000001 sign( sign( sign( sign( sign( sign( sign( sign( sign( sign( sign( sign( sign( sign( sign( sign( -1) = 1000000000000001 -2) = 1000000000000010 -4) = 1000000000000100 -8) = 1000000000001000 -16) = 1000000000010000 -32) = 1000000000100000 -64) = 1000000001000000 -128) = 1000000010000000 -256) = 1000000100000000 -512) = 1000001000000000 -1024) = 1000010000000000 -2048) = 1000100000000000 -4096) = 1001000000000000 -8192) = 1010000000000000 -16384) = 1100000000000000 -32768) = 1000000000000000 cmpl( cmpl( cmpl( cmpl( cmpl( cmpl( cmpl( cmpl( cmpl( cmpl( -1) = 1111111111111111 -2) = 1111111111111110 -4) = 1111111111111100 -8) = 1111111111111000 -16) = 1111111111110000 -32) = 1111111111100000 -64) = 1111111111000000 -128) = 1111111110000000 -256) = 1111111100000000 -512) = 1111111000000000 Programmierkurs I (HTML, CSS, Java) - 85 Java, Vererbung cmpl( cmpl( cmpl( cmpl( cmpl( cmpl( -1024) = 1111110000000000 -2048) = 1111100000000000 -4096) = 1111000000000000 -8192) = 1110000000000000 -16384) = 1100000000000000 -32768) = 1000000000000000 Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( Integer( -1) = 11111111111111111111111111111111 -2) = 11111111111111111111111111111110 -4) = 11111111111111111111111111111100 -8) = 11111111111111111111111111111000 -16) = 11111111111111111111111111110000 -32) = 11111111111111111111111111100000 -64) = 11111111111111111111111111000000 -128) = 11111111111111111111111110000000 -256) = 11111111111111111111111100000000 -512) = 11111111111111111111111000000000 -1024) = 11111111111111111111110000000000 -2048) = 11111111111111111111100000000000 -4096) = 11111111111111111111000000000000 -8192) = 11111111111111111110000000000000 -16384) = 11111111111111111100000000000000 -32768) = 11111111111111111000000000000000 Vergleiche auch die Hüll-Klassen java.lang.Integer und java.lang.Long. Für die Klassen java.lang.Byte und java.lang.Short existieren keine vergleichbaren Methoden. © Universität Mannheim, Rechenzentrum, 1998-2004. Programmierkurs I (HTML, CSS, Java) - 86 Java, Packages 11. Java, Packages 11.1. Packages und Ausnahmen • Packages • Umfang der JDKs • Sichtbarkeit • Ausnahmen Packages Ein Package (Paket) enthält eine oder mehrere Klassen, die sich einen Geltungsbereich (Namespace) für Klassen teilen. Klassennamen brauchen nur innerhalb eines Packages eindeutig zu sein. Dies vermeidet mögliche Namenskonflikte zwischen verschiedenen Klassen, die von der lokalen Festplatte oder über das Netz dynamisch geladen werden. Um eine Java-Datei einem Paket zuzuordnen, kann man an den Anfang der Datei eine package-Anweisung schreiben. package game; Dies definiert das Package game, das die in der Datei definierten Klassen enthält. Falls die Datei keine package-Anweisung enthält, werden die in der Datei definierten Klassen dem standardmäßigen namenlosen Package zugeordnet. Wenn man in einer Datei Klassen eines anderen Packages benutzen will, muß man den Klassennamen komplett mit Package-Namen angeben. Will man z.B. die Klasse Date im java.util-Package benutzen, so wird dies wie im unten angeführten Beispiel getan. java.util.Date d = new java.util.Date(); System.out.println("today is: "+d); Die vollen Packagenamen können weggelassen werden, wenn die import-Anweisung benutzt wird. import java.util.Date; ... Date d = new Date(); System.out.println("today is: "+d); Man kann auch mit * alle Klassennamen eines Packages oder alle Methoden und Variablen einer Klasse importieren. import java.util.*; ... Date d = new Date(); System.out.println("today is: "+d); ... Vector v = new Vector(); v.addElement("hello"); v.addElement("bye"); Das Package java.lang enthält die Basisklassen für Java und wird immer importiert. Deswegen kann man z.B. Object, System, Integer usw. ohne ihren Package-Namen java.lang benutzen. Umfang der JDKs Das Java-API (Application Programming Interface) (JDK-1.0) besteht aus den Klassen, die in den folgenden acht Packages Programmierkurs I (HTML, CSS, Java) - 87 Java, Packages definiert sind: java.applet java.awt java.awt.image java.awt.peer java.io java.lang java.net java.util Bei dem Java-1.1-API (JDK-1.1) haben sich die genannten Packages leicht geändert und es sind die folgenden Packages hinzu gekommen: java.beans java.event java.math java.rmi java.sql java.text java.util.zip Komponenten Bei dem Java-2-API (JDK-1.2) kommen neben vielen Erweiterungen und Verbesserungen vorhandener Pakete, unter anderem folgende Pakete hinzu: java.security java.awt.swing java.awt.accessability java.lang.ref interact with CG java.lang.reflect java.util.jar javax.swing javax.servlet org.omg.CORBA Bei dem Java-2-API (JDK-1.3) kommen neben Erweiterungen zum JDK-1.2 und Verbesserungen vorhandener Pakete, unter anderem folgende Pakete hinzu: java.geom javax.naming javax.sound org.omg.CORBA_2_3 2D Grafik JNDI Bei dem Java-2-API (JDK-1.4) kommen neben Erweiterungen zum JDK-1.3 und Verbesserungen vorhandener Pakete, unter anderem folgende Pakete hinzu: java.nio javax.xml org.w3c org.xml org.ietf.jgss javax.net.ssl javax.imageio new I/O XML W3C DOM SAX security Code-Umfang der JDKs Abbildung: Lines-of-Code der JDKs was \ JDK Version 1.0.2 1.1.8 1.2.2 1.3.1 1.4.0 lines of Java code 36.080 152.347 502.726 574.034 1.183.279 words in Java code 156.799 707.193 2.085.638 2.373.953 4.718.321 bytes in src-dir 1.0 MB 7.0 MB 20.0 MB 24.0 MB 48.0 MB Programmierkurs I (HTML, CSS, Java) - 88 Java, Packages public class or interface 122 736 1.649 1.952 3.993 directories / packages 14 35 88 98 238 @authors, see 1 21 114 100 236 315 1.319 4.648 18.209 23.190 44.006 for ( ) 236 1.692 2.727 5.065 10.031 if ( ) while ( ) 105 269 985 1.134 1.625 switch ( ) 33 107 410 465 839 try { } 93 112 507 602 2.143 catch ( ) 108 307 909 1.126 3.505 throw new 167 709 2.011 2.294 6.700 boolean 322 1.029 4.286 4.818 9.532 1.556 5.043 19.613 21.599 41.679 long 130 810 754 1.890 3.250 float 43 104 1.030 1.134 1.625 double 71 181 1.057 1.427 1.862 public 1.976 5.828 21.110 24.368 50.209 private 303 1.948 5.120 6.477 13.900 protected 151 689 3.695 4.201 6.399 abstract class 17 74 214 319 545 2.268 6.503 22.443 25.492 49.592 int /** comments */, see 2 Bemerkungen: 1. ohne Namen zu normalisieren und nur die genannten 2. d.h. öffentliche mit javadoc dokumentierte Objekte Die Zahlen wurden im wesentlichen mit grep pattern cat.java|wc ermittelt. Die Datei cat.java wurde mit find src-dir -name "*.java" |xargs cat > cat.java erzeugt. Daneben gibt es in den jeweiligen JDKs noch viele class-Dateien ohne java-Dateien, wo also der Source-Code nicht bekannt ist. Zugriff und Sichtbarkeit Eine als public deklarierte Klasse ist in allen Packages zugreifbar. Auf eine nicht als public deklarierte Klasse kann nur innerhalb desselben Package zugegriffen werden. Zur Verdeutlichung der Konzepte betrachten wir folgende Beispiele: public class A public protected private /*default*/ } { int int int int pb; pt; pv; df; public class B extends A { A a = new A(); /* 1 */ } public class C { Programmierkurs I (HTML, CSS, Java) - 89 Java, Packages A a = new A(); /* 2 */ } An der Stelle /* 1 */ gilt folgendes: • falls A und B im gleichen Package sind, sind pb, pt, df sowie a.pb, a.pt, a.df sichtbar • falls A und B in verschiedenen Packages sind, sind pb, pt und a.pb sichtbar An der Stelle /* 2 */ gilt: • falls A und C im gleichen Package sind, sind a.pb, a.pt, a.df sichtbar • falls A und C in verschiedenen Packages sind, ist nur a.pb sichtbar Abbildung 1.2: Java-Sichtbarkeit Sichtbarkeit public protected default package private Klasse/Objekt definierende Klasse ja ja ja ja gleiches Package ja ja ja nein anderes Package ja nein nein nein gleiches Package ja ja ja nein anderes Package ja ja nein nein Vererbung Auf public-Felder (Variablen oder Methoden) kann in allen Packages und Subklassen zugegriffen werden, solange die Klasse selbst zugreifbar ist. Auf protected-Felder kann in Subklassen der Klasse und in allen Klassen im gleichen Package zugegriffen werden. private-Felder sind dagegen nur in derselben Klasse zugreifbar. Diese Beziehungen sind nochmal in Abbildung 1.2 zusammengefaßt. Konstanten Konstante Variablen können mit dem Schlüsselwort final deklariert werden. Diese können dann nicht mehr geändert werden. public final static String DEFAULT = "dpunkt"; Im Gegensatz zu C oder C++ gibt es keinen Preprozessor, der Konstanten substituieren kann (z.B. kein #define). Final-Klassen Von Klassen, die mit dem Schlüsselwort final deklariert sind, können keine Klassen abgeleitet werden. Dies dient zum einen dazu, unerwünschte Ableitungen zu verhindern, wie zum Beispiel bei system-nahen Klassen java.lang.System. Und sie dienen zum anderen dazu, dem Compiler Hinweise für die Optimierung zugeben, denn es müssen dann keine Vorkehrungen zum Überschreiben dieser Methoden getroffen werden. Ausnahmebehandlung Ein Ausnahmefehler (Exception) ist ein Signal, das irgendeinen Fehler andeutet. Man kann eine Exception durch throw auslösen und durch catch abfangen. Ein neues Exception-Objekt wird wie üblich mit new erzeugt. Java unterscheidet im Wesentlichen drei Arten von Ausnahmen, die alle von der Klasse java.lang.Throwable abgeleitet sind: Exception: Für eine Anwendung wichtige Informationen, die für die weitere Verarbeitung entsprechend behandelt werden sollte. Der Programmierkurs I (HTML, CSS, Java) - 90 Java, Packages Compiler achtet darauf, dass Exceptions behandelt oder weitergereicht werden. RuntimeException Ebenfalls wichtige Information, die bei Bedarf der Anwendung behandelt werden kann oder zum Abbruch der Anwendung führen sollte. Sie werden vom Compiler nicht explizit beachtet. Error Unvorhergesehener Fehler, der in der Regel zum Abbruch der Anwendung führen sollte. Sie werden vom Compiler nicht explizit beachtet. Falls eine Exception nicht in der Methode abgefangen wird, wird sie in die Methode weitergeleitet, die diese Methode aufgerufen hat. Dies ermöglicht bessere und einfachere Fehlerbehandlung. Jede Methode in Java muß Exceptions entweder explizit abfangen oder weiterleiten. Zum Abfangen kann man try und catch wie folgt benutzen. try { // open a file ... // read data ... } catch (IOException e) { System.out.println("Couldn't write"); // do the clean up, e.g. closing the file } Die vollständige Syntax dieser Anweisungsfolge ist: try { // statements possibly generating // Exception_1 or Exception_2 } catch (Exception_1 // statements } catch (Exception_2 // statements } ... finally { // statements } e) { handling Exception_1 e) { handling Exception_2 cleaning up for all the cases Der finally-Block wird unabhängig vom Auftreten von Ausnahmen zum Schluß ausgeführt. Zum Weiterleiten von Ausnahmen kann man das throws-Schlüsselwort benutzen. throws wird zwischen dem Methodenkopf und dem Methodenrumpf zusammen mit einer Aufzählung aller in Frage kommenden Ausnahmen eingefügt. Zum Auslösen von Ausnahmen verwendet man das throw-Schlüsselwort. public void getInputData() throws MyException { ... if (notOK) { throw new MyException(); } ... } Zur Definition einer Ausnahme wird eine Subklasse von java.lang.Exception gebildet. class MyException extends Exception { public MyException() { ...; } public MyException(String msg) { ...; } } java.lang.Exception ist eine direkte Subklasse von java.lang.Throwable: public class Exception Programmierkurs I (HTML, CSS, Java) - 91 Java, Packages extends Throwable implements Serializable Exception() Exception(String message) Exception(String message, Throwable cause) Exception(Throwable cause) Throwable getCause() Throwable initCause(Throwable cause) String getMessage() void printStackTrace() Beispiele: public class Ausnahmen { public void exception() throws NumberFormatException { int n = 0; try { // versuche irgendwelche Methodenaufrufe, die // Ausnahmen produzieren koennen } catch (IndexOutOfBoundsException e1) { // Fehlerbehandlung // meist Ausgabe einer Fehlermeldung // das Programm arbeitet dann weiter // nach dem letzten catch-Block } catch (Exception e2) { // hier werden alle Ausnahmen abgefangen // die nicht schon vorher behandelt // wurden } finally { // dieser Block ist optional, er wird nach // jedem Verlassen des try-Blocks ausgefuehrt } if (n < 0) throw new NumberFormatException("Die Variable n enthaelt"+ " einen Wert kleiner als 0!"); } } © Universität Mannheim, Rechenzentrum, 1998-2004. Programmierkurs I (HTML, CSS, Java) - 92 Java, Ströme 12. Java, Ströme 12.1. Ein- und Ausgabe Ströme • String, StringBuffer • Math • Datenströme • System • Objekt-Ströme String, StringBuffer Zeichenketten mit der Klasse String. Diese Objekte sind 'immutable', d.h. sie werden nie modifiziert, sondern immer neu erzeugt. public final class String extends Object implements Serializable, Comparable String() String(String) String(StringBuffer) String(char[]) char charAt(int) int compareTo(String) // returns -1, 0, +1 String concat(String) boolean endsWith(String) boolean equals(Object) boolean equalsIgnoreCase(String) void getChars(int srcb, int srce, char[] dst, int dstb) int indexOf(String) int length() String replace(char alt, char neu) boolean startsWith(String) String substring(int von) String substring(int von, int bis) char[] toCharArray() String toLowerCase( . ) String toUpperCase( . ) String trim() String valueOf( . ) Programmierkurs I (HTML, CSS, Java) - 93 Java, Ströme String UML Diagramm Zeichenketten mit der Klasse StringBuffer. Diese Objekte sind veränderbar. public final class StringBuffer extends Object implements Serializable StringBuffer() StringBuffer(String) Programmierkurs I (HTML, CSS, Java) - 94 Java, Ströme StringBuffer(int) char charAt(int) void getChars(int srcb, int srce, char[] dst, int dstb) int capacity() int length() void setCharAt(int, char) void setLength(int) StringBuffer StringBuffer StringBuffer StringBuffer append( . ) insert(int, . ) delete(int, int) deleteCharAt(int) // // // // returns returns returns returns this this this this StringBuffer reverse() // returns this String substring(int von) String substring(int von, int bis) StringBuffer UML Diagramm Math Die Klasse Math stellt eine Reihe von nützlichen Konstanten und Methoden zur Verfügung. Programmierkurs I (HTML, CSS, Java) - 95 Java, Ströme public final class Math extends Object double E double Pi t abs( t ) t max( t, t ) t min( t, t ) acos, asin, atan, atan2, cos, exp, log, sin, sqrt, tan ceil, floor, double pow(double, double) double random() int round(float) long round(double) Hüllklassen: Byte, Short, Integer und Long, so wie Float und Double. Super-Klasse: Number Langzahl Arithmetik in java.lang.Number: BigInteger und BigDecimal. Datenströme Programmierkurs I (HTML, CSS, Java) - 96 Java, Ströme Datenströme Sämtlicher expliziter Datenaustausch in und aus der JVM (Java Virtual Machine) ist in sogenannte Datenströme organisiert: • Character Ströme • Byte Ströme • Object Ströme Character Ströme Programmierkurs I (HTML, CSS, Java) - 97 Java, Ströme Byte Ströme Typische verfügbare Methoden: read() (lesen vom Datenstrom), write() (schreiben in den Datenstrom), close() (Datenstrom schliessen) Beispiel: Lesen von der Tastatur, Schreiben auf den Bildschirm import java.io.PrintWriter; import java.io.OutputStreamWriter; public class Screen extends PrintWriter { public Screen() { super(new OutputStreamWriter(System.out),true); } } import java.io.BufferedReader; import java.io.InputStreamReader; public class KeyBoard extends BufferedReader { public KeyBoard() { Programmierkurs I (HTML, CSS, Java) - 98 Java, Ströme super(new InputStreamReader(System.in)); } } Screen und KeyBoard import java.io.IOException; public class Terminal { public static void main(String[] args) { KeyBoard kb = new KeyBoard(); Screen sc = new Screen(); String ea = ""; try { sc.println( "Beenden mit 'ende'"); do { sc.print( "Bitte um Eingabe: "); sc.flush(); ea = kb.readLine(); sc.println("Eingabe ist "+ea); if ( ea == null ) break; } while ( !ea.equals("ende") ); } catch (IOException e) { e.printStackTrace(); } } } Programmierkurs I (HTML, CSS, Java) - 99 Java, Ströme Beispiel: lesen und schreiben von Dateien import java.io.BufferedReader; import java.io.FileReader; import java.io.FileNotFoundException; public class DateiEin extends BufferedReader { public DateiEin(String name) throws FileNotFoundException { super(new FileReader(name)); } } import java.io.PrintWriter; import java.io.FileWriter; import java.io.IOException; public class DateiAus extends PrintWriter { public DateiAus(String name) throws IOException { super(new FileWriter(name)); } } Datei Ein- und Ausgabe import java.io.IOException; Programmierkurs I (HTML, CSS, Java) - 100 Java, Ströme import java.io.FileNotFoundException; public class Dateien { public static void main(String[] args) { Screen sc = new Screen(); if ( args.length < 1 ) { sc.println("Usage: Dateien <eingabe datei> [<ausgabe datei>]"); return; } DateiEin rein; DateiAus raus = null; try { rein = new DateiEin(args[0]); } catch (FileNotFoundException e) { sc.println("Die Datei " + args[0] + " existiert nicht."); return; } if ( args.length >= 2 ) { try { raus = new DateiAus(args[1]); } catch (IOException e) { sc.println("Die Datei " + args[1] + " ist nicht beschreibbar."); } } String ea = ""; int ein = 0; int aus = 0; try { do { ea = rein.readLine(); if ( ea == null ) break; ein++; if ( raus == null ) { sc.println(ea); } else { raus.println(ea); } aus++; } while ( !ea.equals("ende") ); } catch (IOException e) { e.printStackTrace(); } finally { if ( raus != null ) raus.flush(); } try { rein.close(); if ( raus != null ) raus.close(); } catch (IOException e) { e.printStackTrace(); } sc.println(""+ein+" Zeilen von " + args[0] + " gelesen"); if ( args.length >= 2 ) sc.println(""+aus+" Zeilen auf " + args[1] + " geschrieben"); } } Benutzung: Programmierkurs I (HTML, CSS, Java) - 101 Java, Ströme java Dateien DateiA [DateiB] Beispiel: Anhängen an Dateien import java.io.PrintWriter; import java.io.FileWriter; import java.io.IOException; public class DateiDran extends PrintWriter { public DateiDran(String name) throws IOException { super(new FileWriter(name, true)); } public DateiDran(String name, boolean append) throws IOException { super(new FileWriter(name, append)); } } import java.io.IOException; import java.io.FileNotFoundException; public class Anhang { public static void main(String[] args) { Screen sc = new Screen(); if ( args.length < 2 ) { sc.println("Usage: Anhang <eingabe datei> <ausgabe datei>"); return; } DateiEin rein; DateiDran dran; try { rein = new DateiEin(args[0]); } catch (FileNotFoundException e) { sc.println("Die Datei " + args[0] + " existiert nicht."); return; } try { dran = new DateiDran(args[1]); } catch (IOException e) { sc.println("Die Datei " + args[1] + " ist nicht beschreibbar."); return; } String ea = ""; int ein = 0; int aus = 0; try { do { ea = rein.readLine(); // sc.println("Eingabe: "+ea); if ( ea == null ) break; ein++; dran.println(ea); aus++; } while ( !ea.equals("ende") ); } catch (IOException e) { e.printStackTrace(); } finally { Programmierkurs I (HTML, CSS, Java) - 102 Java, Ströme dran.flush(); } try { rein.close(); dran.close(); } catch (IOException e) { e.printStackTrace(); } sc.println(""+ein+" Zeilen von " + args[0] + " gelesen"); sc.println(""+aus+" Zeilen auf " + args[1] + " geschrieben"); } } Benutzung: java Anhang DateiA DateiB Beispiel: Lesen im Netzwerk import import import import java.io.BufferedReader; java.io.InputStreamReader; java.io.IOException; java.net.URL; public class URLEin extends BufferedReader { public URLEin(String url) throws IOException { super(new InputStreamReader( (new URL(url)).openStream() ) ); } } import java.io.IOException; public class URLs { public static void main(String[] args) { Screen sc = new Screen(); if ( args.length < 1 ) { sc.println("Usage: Dateien <eingabe url> [<ausgabe datei>]"); return; } URLEin rein; DateiAus raus = null; try { rein = new URLEin(args[0]); } catch (IOException e) { sc.println("Von URL " + args[0] + " kann nicht gelesen werden."); return; } if ( args.length >= 2 ) { try { raus = new DateiAus(args[1]); } catch (IOException e) { sc.println("Die Datei " + args[1] + " ist nicht beschreibbar."); Programmierkurs I (HTML, CSS, Java) - 103 Java, Ströme return; } } String ea = ""; int ein = 0; int aus = 0; try { do { ea = rein.readLine(); if ( ea == null ) break; ein++; if ( raus != null ) { raus.println(ea); } else { sc.println(ea); } aus++; } while ( !ea.equals("ende") ); } catch (IOException e) { e.printStackTrace(); } finally { if ( raus != null ) raus.flush(); } try { rein.close(); if ( raus != null ) raus.close(); } catch (IOException e) { e.printStackTrace(); } sc.println(""+ein+" Zeilen von " + args[0] + " gelesen"); sc.print(""+aus+" Zeilen"); if ( args.length >= 2 ) sc.print(" auf "+args[1]); sc.println(" geschrieben"); } } Benutzung: java URLs http://www.uni-mannheim.de/ [Datei] System Die Klasse System stellt eine Reihe von Variablen und Klassen-Methoden zum plattform-unabhängigen Zugriff auf das Computersystem zur Verfügung. public final class System extends Object PrintStream err InputStream in PrintStream out void setErr(PrintStream) void setIn(InputStream) void setOut(PrintStream) void arraycopy(Object, int, Object, int, int len) long currentTimeMillis() // Zeit seit 1. Jan 1970 Programmierkurs I (HTML, CSS, Java) - 104 Java, Ströme void exit(int) void gc() Properties getProperties() String getProperty(String) String getProperty(String, String) void setProperties(Properties) SecurityManager getSecurityManager() void setSecurityManager(SecurityManager) System UML Diagramm Objekt-Ströme import java.io.ObjectInputStream; import java.io.FileInputStream; import java.io.IOException; public class ObjectEin extends ObjectInputStream { public ObjectEin(String name) throws IOException { super(new FileInputStream(name)); } } Programmierkurs I (HTML, CSS, Java) - 105 Java, Ströme import java.io.ObjectOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class ObjectAus extends ObjectOutputStream { public ObjectAus(String name) throws IOException { super(new FileOutputStream(name)); } } ObjectStreams import java.io.IOException; import java.io.FileNotFoundException; import java.io.OptionalDataException; public class Objekte { public static void main(String[] args) { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); final int MAX = 100; String[] data = null; if ( args.length < 1 ) { sc.println("Usage: Dateien <speicher datei>"); return; } Programmierkurs I (HTML, CSS, Java) - 106 Java, Ströme ObjectEin rein = null; ObjectAus raus; try { rein = new ObjectEin(args[0]); } catch (FileNotFoundException e) { sc.println("Die Datei " + args[0] + " existiert nicht."); } catch (IOException e) { sc.println("Die Datei " + args[0] + " nicht lesbar."); } if ( rein != null ) { try { data = (String[]) rein.readObject(); rein.close(); } catch (OptionalDataException e) { sc.println("Zuviel Daten in Datei " + args[0]); } catch (ClassNotFoundException e) { sc.println("Zu lesende Klasse nicht bekannt in Datei " + args[0]+ ": "+e); } catch (IOException e) { sc.println("Lesefehler von Datei " + args[0]); } } if ( data == null ) { data = new String[MAX]; } try { raus = new ObjectAus(args[0]); } catch (IOException e) { sc.println("Die Datei " + args[0] + " ist nicht beschreibbar."); return; } String ea int zeile int ein = int aus = = ""; = -1; // leer 0; 0; sc.println("Aktueller Inhalt von " + args[0]); for ( zeile = 0; zeile < MAX; zeile++ ) { if ( data[zeile] == null ) break; sc.println("" + zeile + ": " + data[zeile] ); } // zeile zeigt jetzt auf einen freien Platz in data zeile--; sc.println(""+(zeile+1)+" Zeilen in " + args[0] + " enthalten\n"); try { sc.println( "Beenden mit 'ende'"); do { sc.print( "Bitte um Eingabe: "); sc.flush(); ea = kb.readLine(); if ( ea == null ) break; if ( ea.equals("ende") ) break; ein++; sc.println("Eingabe: "+(zeile+1)+": " +ea); zeile++; if ( zeile < MAX ) data[zeile] = ea; aus++; } while (true); } Programmierkurs I (HTML, CSS, Java) - 107 Java, Ströme catch (IOException e) { e.printStackTrace(); } finally { try { raus.writeObject(data); raus.close(); } catch (IOException e) { sc.println("Fehler beim Schreiben auf Die Datei " + args[0]); } } sc.println(); sc.println(""+ein+" Zeile(n) von der Tastatur gelesen"); sc.println(""+aus+" Zeile(n) auf den Bildschirm geschrieben"); sc.println(""+(zeile+1)+" Zeile(n) nach " + args[0] + " geschrieben"); } } Benutzung: java Objekte xx Aktueller Inhalt von xx 0: a 1: b 2: c 3: ddddddddddddddd 4: e 5: f 6 Zeilen in xx enthalten Beenden mit 'ende' Bitte um Eingabe: 1 Eingabe: 6: 1 Bitte um Eingabe: 2 Eingabe: 7: 2 Bitte um Eingabe: 3 Eingabe: 8: 3 Bitte um Eingabe: 3 Zeile(n) von der Tastatur gelesen 3 Zeile(n) auf den Bildschirm geschrieben 9 Zeile(n) nach xx geschrieben Persistenz Dauerhafte nicht flüchtige Objekte Speichern der Objekte auf externen Datenträgern import java.io.IOException; import java.io.FileNotFoundException; import java.io.OptionalDataException; public class PersObjekt { public final int MAX = 100; private String[] data = null; private String fileName = "PersObjekt.temp"; private ObjectEin rein = null; private ObjectAus raus; private Screen sc = new Screen(); public PersObjekt(String filename) throws IOException { Programmierkurs I (HTML, CSS, Java) - 108 Java, Ströme if ( filename != null ) if ( !filename.equals("") ) fileName = filename; restore(); if ( data == null ) { data = new String[MAX]; } raus = new ObjectAus(fileName); } protected void restore() throws IOException { try { rein = new ObjectEin(fileName); } catch (FileNotFoundException e) { throw new IOException("Die Datei " + fileName + " existiert nicht " + e); } if ( rein != null ) { try { data = (String[]) rein.readObject(); rein.close(); } catch (OptionalDataException e) { throw new IOException("Zuviel Daten in Datei " + fileName + e); } catch (ClassNotFoundException e) { throw new IOException("Zu lesende Klasse nicht bekannt in Datei " + fileName + e); } } } protected void store() throws IOException { raus.writeObject(data); raus.close(); sc.println(fileName + " geschrieben"); } public String[] getData() { return data; } public void setData(String[] d) { data = d; } protected void finalize() throws IOException { store(); } } import java.io.IOException; import java.io.FileNotFoundException; import java.io.OptionalDataException; public class Persistenz { public static void main(String[] args) throws IOException { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); PersObjekt pers = null; String pname = "PersObjekt.temp"; if ( args.length > 0 ) { pname = args[0]; Programmierkurs I (HTML, CSS, Java) - 109 Java, Ströme } pers = new PersObjekt(pname); String[] data = pers.getData(); String ea int zeile int ein = int aus = = ""; = -1; // leer 0; 0; sc.println("Aktueller Inhalt von " + pname); for ( zeile = 0; zeile < pers.MAX; zeile++ ) { if ( data[zeile] == null ) break; sc.println("" + zeile + ": " + data[zeile] ); } // zeile zeigt jetzt auf einen freien Platz in data zeile--; sc.println(""+(zeile+1)+" Zeilen in " + pname + " enthalten\n"); try { sc.println( "Beenden mit 'ende'"); do { sc.print( "Bitte um Eingabe: "); sc.flush(); ea = kb.readLine(); if ( ea == null ) break; if ( ea.equals("ende") ) break; ein++; sc.println("Eingabe: "+(zeile+1)+": " +ea); zeile++; if ( zeile < pers.MAX ) data[zeile] = ea; aus++; } while (true); } catch (IOException e) { e.printStackTrace(); } finally { pers.setData(data); // unnötig pers.store(); // pers = null; // System.gc(); // call finalize } sc.println(); sc.println(""+ein+" Zeile(n) von der Tastatur gelesen"); sc.println(""+aus+" Zeile(n) auf den Bildschirm geschrieben"); } } Benutzung: java Persistenz xx Aktueller Inhalt von xx 0: a 1: b 2: c 3: ddddddddddddddd 4: e 5: f 6: 1 7: 2 8: 3 9 Zeilen in xx enthalten Beenden mit 'ende' Bitte um Eingabe: I Eingabe: 9: I Bitte um Eingabe: II Programmierkurs I (HTML, CSS, Java) - 110 Java, Ströme Eingabe: 10: II Bitte um Eingabe: III Eingabe: 11: III Bitte um Eingabe: IV Eingabe: 12: IV Bitte um Eingabe: ende xx geschrieben 4 Zeile(n) von der Tastatur gelesen 4 Zeile(n) auf den Bildschirm geschrieben © Universität Mannheim, Rechenzentrum, 1998-2004. Last modified: Sat Oct 23 16:36:40 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 111 Java, Utilities 13. Java, Utilities 13.1. Collection-Klassen, I18N • Collection, Set, List • Map • Date • Calendar • DateFormat • Locale • ResouceBundle Collections Interfaces: • java.util.Collection • java.util.List • java.util.Set • java.util.SortedSet • java.util.Map • java.util.SortedMap • java.util.Iterator Klassen: • java.util.LinkedList • java.util.Vector • java.util.ArrayList • java.util.HashMap • java.util.Hashtable • java.util.TreeMap Programmierkurs I (HTML, CSS, Java) - 112 Java, Utilities Collection, Set, List Collection: public interface Collection Programmierkurs I (HTML, CSS, Java) - 113 Java, Utilities public public public public boolean add(Object o) boolean remove(Object o) boolean contains(Object o) Iterator iterator() Iterator: public interface Iterator public boolean hasNext() public Object next() List: Duplikate sind zugelassen public interface List extends Collection public public public public public boolean add(Object o) Object get() boolean remove(Object o) boolean contains(Object o) Iterator iterator() Set: keine Duplikate enthalten public interface Set extends Collection public public public public boolean add(Object o) boolean remove(Object o) boolean contains(Object o) Iterator iterator() Comparator: Vergleichsmethode bei Sorted* public interface Comparator int compare(Object o1, Object o2) boolean equals(Object obj) Programmierkurs I (HTML, CSS, Java) - 114 Java, Utilities Programmierkurs I (HTML, CSS, Java) - 115 Java, Utilities Map, SortedMap Map: (Schlüssel,Wert)-Paare public interface Map public public public public public public boolean put(Object key, Object value) Object get(Object key) boolean remove(Object key) boolean containsKey(Object key) boolean containsValue(Object value) Set keySet() Objekte, die als Schlüssel (key) verwendet werden, müssen folgende Bedingungen erfüllen: • equals() sollte für inhaltlich gleiche Objekte true liefern, d.h. equals() von Object muss in der Regel überschrieben werden denn das von Object geerbte equals() liefert nur für das selbe Objekt true • hashCode() muss für Objekte, für die equals() wahr ist, auch die gleiche Zahl liefern d.h. falls a.equals(b) == true muss a.hashCode() == b.hashCode() sein denn das von Object geerbte hashCode() liefert nur für das selbe Objekt die gleiche int-Zahl Beispiel: Konten als HashMap import import import import java.util.HashMap; java.util.Iterator; java.util.Set; java.util.Map.Entry; public class Konten { private HashMap konten = null; public Konten() { konten = new HashMap(); } public void buche(int nummer, double betrag) { Integer n = new Integer(nummer); Object v = konten.get(n); double s = 0.0; if (v instanceof Double) { s = ((Double)v).doubleValue(); } konten.put(n, new Double(s+betrag)); } public double stand(int nummer) { Integer n = new Integer(nummer); Object v = konten.get(n); Double s = null; if (v instanceof Double) { s = (Double) v; } else { s = new Double(0.0); } return s.doubleValue(); } public String toString(int nummer) { String s = ""; s += "<Konto"; s += " nummer='" + nummer + "'"; s += " stand='" + stand(nummer) + "'"; s += " />"; return s; } Programmierkurs I (HTML, CSS, Java) - 116 Java, Utilities public String toString() { String s = ""; s += "<Konten >\n"; for (Iterator i = (konten.keySet()).iterator(); i.hasNext(); ) { Object e = i.next(); Integer n = (Integer)e; int nummer = n.intValue(); s += toString(nummer) + "\n"; } s += "</Konten>"; return s; } } Collections: statische Hilfsmethoden public class Collections extends Object static int binarySearch(List list, Object key) static int binarySearch(List list, Object key, Comparator c) static void copy(List dest, List src) static void fill(List list, Object obj) static int indexOfSubList(List source, List target) static int lastIndexOfSubList(List source, List target) static Object max(Collection coll) static Object max(Collection coll, Comparator comp) static Object min(Collection coll) static Object min(Collection coll, Comparator comp) static List nCopies(int n, Object o) static boolean replaceAll(List list, Object oldVal, Object newVal) static void reverse(List list) static Comparator reverseOrder() static void rotate(List list, int distance) static void shuffle(List list) static void shuffle(List list, Random rnd) static void sort(List list) static void sort(List list, Comparator c) static void swap(List list, int i, int j) Date java.util.Date stellt Datum und Uhrzeiten dar. Die Zeit wird als Millisekunden seit dem 1. Januar 1970, 0 Uhr gespeichert. Fast alle Methoden sind 'deprecated'. public class Date extends Object implements Serializable, Cloneable, Comparable public Date() public Date(long millis) public long getTime() public void setTime(long millis) public boolean after(Date a) Programmierkurs I (HTML, CSS, Java) - 117 Java, Utilities public boolean before(Date a) public boolean equals(Date a) Beispiel: Zeitstempel in einem Buchungssatz (vonKonto, nachKonto, Betrag, Zeitstempel) import java.util.Date; public class BuchungDate implements BuchungInterface { final static int NO_KONTO = -1; protected int vonKonto = NO_KONTO; protected int nachKonto = NO_KONTO; protected double betrag = 0.0; protected Date zeitStempel = null; public BuchungDate(int von, int nach, double b) { vonKonto = von; nachKonto = nach; betrag = b; zeitStempel = new Date(); } public int getVonKonto() { return vonKonto; } public int getNachKonto() { return nachKonto; } public double getBetrag() { return betrag; } public Date getZeit() { return zeitStempel; } public boolean vor(BuchungInterface b) { return zeitStempel.before( b.getZeit() ); } public boolean nach(BuchungInterface b) { return zeitStempel.after( b.getZeit() ); } public String toString() { String s = "<BuchungDate"; s += " von='"+vonKonto+"'"; s += " nach='"+vonKonto+"'"; s += " betrag='"+betrag+"'"; s += " zeit='"+zeitStempel+"'"; s += " />"; return s; } } das verwendete Interface: import java.util.Date; public interface BuchungInterface { public int getVonKonto(); public int getNachKonto(); public double getBetrag(); public Date getZeit(); public boolean vor(BuchungInterface b); public boolean nach(BuchungInterface b); Programmierkurs I (HTML, CSS, Java) - 118 Java, Utilities } Test Programm static void testDate() { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); String s = ""; BuchungInterface a = new BuchungDate(1,9,50.0); try { sc.println("press enter to continue"); s = kb.readLine(); } catch(IOException e) { } BuchungInterface b = new BuchungDate(9,2,100.0); sc.println("a = " + a); sc.println("b = " + b); boolean t = a.vor(b); sc.println("t = " + t); t = a.nach(b); sc.println("t = " + t); sc.println(); } Ausgabe press enter to continue a b t t = = = = <BuchungDate von='1' nach='9' betrag='50.0' zeit='Sun Dec 16 17:02:49 CET 2001' /> <BuchungDate von='9' nach='2' betrag='100.0' zeit='Sun Dec 16 17:02:50 CET 2001' /> true false Calendar und DateFormat java.util.Calendar stellt Datum und Uhrzeit unabhängig von den o.g. Millisekunden dar. Objekte der abstrakten Klasse können nicht per Konstruktor erzeugt werden, sondern es gibt eine Methode getInstance() die ein Objekt der Klasse liefert. public abstract class Calendar extends Object implements Serializable, Cloneable public static Calendar getInstance() public static Calendar getInstance(TimeZone t, Locale l) public final Date getTime() public final void setTime(Date d) public final TimeZone getTimeZone() public final void setTimeZone(TimeZone t) public public public public final final final final int get(int feld) void set(int feld, int wert) void add(int feld, int wert) void roll(int feld, int wert) public static final int YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, ..., DAY_OF_YEAR, ... public final void set(int jahr, int monat, int tag) public final void set(int jahr, int monat, int tag, int stunde) public final void set(int jahr, int monat, int tag, int stunde, int minute) Programmierkurs I (HTML, CSS, Java) - 119 Java, Utilities public final void set(int jahr, int monat, int tag, int stunde, int minute, int sekunde) public boolean after(Object a) public boolean before(Object a) public boolean equals(Object a) java.util.GregorianCalendar erweitert die Klasse Calendar. import java.util.Date; import java.util.Calendar; import java.text.DateFormat; public class BuchungCalendar implements BuchungInterface { final static int NO_KONTO = -1; protected int vonKonto = NO_KONTO; protected int nachKonto = NO_KONTO; protected double betrag = 0.0; protected Calendar zeitStempel = null; protected DateFormat zeitFormat = null; public BuchungCalendar(int von, int nach, double b) { vonKonto = von; nachKonto = nach; betrag = b; zeitStempel = Calendar.getInstance(); zeitStempel.setTime( new Date() ); zeitFormat = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL); } public int getVonKonto() { return vonKonto; } public int getNachKonto() { return nachKonto; } public double getBetrag() { return betrag; } public Date getZeit() { return zeitStempel.getTime(); } public boolean vor(BuchungInterface b) { return zeitStempel.before( b.getZeit() ); } public boolean nach(BuchungInterface b) { return zeitStempel.after( b.getZeit() ); } public String toString() { String s = "<" + getClass().getName(); s += " von='"+vonKonto+"'"; s += " nach='"+nachKonto+"'"; s += " betrag='"+betrag+"'"; s += " zeit='"+zeitFormat.format(zeitStempel.getTime())+"'"; s += " />"; return s; } } java.text.DateFormat formatiert Datum und Uhrzeit entsprechend einer Sprach- und Landes-Einstellung java.util.Locale. Auch die Objekte dieser abstrakten Klasse können nicht per Konstruktor erzeugt werden, sondern es gibt Methoden getInstance() die ein Objekt der Klasse liefern. public abstract class DateFormat extends Format Programmierkurs I (HTML, CSS, Java) - 120 Java, Utilities public static final DateFormat getInstance() public static final DateFormat getDateInstance() public static final DateFormat getTimeInstance() public static final DateFormat getDateTimeInstance() public static final DateFormat getDateInstance(int dStyle) public static final DateFormat getTimeInstance(int tStyle) public static final DateFormat getDateTimeInstance(int dStyle, int tStyle) public static final DateFormat getDateInstance(int dStyle, Locale l) public static final DateFormat getTimeInstance(int tStyle, Locale l) public static final DateFormat getDateTimeInstance(int dStyle, int tStyle, Locale l) public static final int DEFAULT, FULL, LONG, MEDIUM, SHORT public final String format(Date d) public final StringBuffer format(Object n_d, StrinBuffer to, FieldPosition f) public final Date parse(String s) public final Object parseObject(String s, ParsePosition p) Beispiele: Verwendung von Calender und DateFormat static void testCalendar() { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); String s = ""; BuchungInterface a = new BuchungCalendar(1,9,50.0); try { sc.println("press enter to continue"); s = kb.readLine(); } catch(IOException e) { } BuchungInterface b = new BuchungCalendar(9,2,100.0); sc.println("a = " + a); sc.println("b = " + b); boolean t = a.vor(b); sc.println("t = " + t); t = a.nach(b); sc.println("t = " + t); sc.println(); } Ausgabe press enter to continue a b t t = = = = <BuchungCalendar von='1' nach='9' betrag='50.0' zeit='Sonntag, 16. Dezember 2001 17.02 Uhr CET' /> <BuchungCalendar von='9' nach='2' betrag='100.0' zeit='Sonntag, 16. Dezember 2001 17.02 Uhr CET' /> false false Locale java.util.Locale stellt Sprache, Land und weitere Feinheiten dar. Es existieren eine ganze Reihe von vordefinierten Locale-Objekten. public final class Locale Programmierkurs I (HTML, CSS, Java) - 121 Java, Utilities extends Object implements Cloneable, Serializable public Locale(String sprace, String land) public Locale(String sprace, String land, String feinheit) public static final Locale GERMANY, US, FRANCE, JAPAN, CHINA, ... public static final Locale GERMAN, ENGLISH, FRENCH, JAPANESE, CHINESE, ... public static Locale getDefault() public static void setDefault(Locale l) public public public public final final final final String String String String getDisplayCountry() getDisplayLanguage() getDisplayName() getDisplayVariant() import java.util.Locale; import java.text.DateFormat; public class BuchungCalendarFrance extends BuchungCalendar { public BuchungCalendarFrance(int von, int nach, double b) { super(von,nach,b); zeitFormat = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, Locale.FRANCE); } } static void testCalendarFrance() { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); String s = ""; BuchungInterface a = new BuchungCalendarFrance(1,9,50.0); BuchungInterface b = new BuchungCalendarFrance(9,2,100.0); sc.println("a = " + a); sc.println("b = " + b); boolean t = a.vor(b); sc.println("t = " + t); sc.println(); } import java.util.Locale; import java.text.DateFormat; public class BuchungCalendarItaly extends BuchungCalendar { public BuchungCalendarItaly(int von, int nach, double b) { super(von,nach,b); zeitFormat = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, Locale.ITALY); } } import java.util.Locale; import java.text.DateFormat; public class BuchungCalendarJapan extends BuchungCalendar { Programmierkurs I (HTML, CSS, Java) - 122 Java, Utilities public BuchungCalendarJapan(int von, int nach, double b) { super(von,nach,b); zeitFormat = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, Locale.JAPAN); } } import java.util.Locale; import java.text.DateFormat; public class BuchungCalendarUS extends BuchungCalendar { public BuchungCalendarUS(int von, int nach, double b) { super(von,nach,b); zeitFormat = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, Locale.US); } } static void testCalendarUS() { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); String s = ""; BuchungInterface a = new BuchungCalendarUS(1,9,50.0); BuchungInterface b = new BuchungCalendarUS(9,2,100.0); sc.println("a = " + a); sc.println("b = " + b); boolean t = a.vor(b); sc.println("t = " + t); sc.println(); } Ausgabe a = <BuchungCalendarUS von='1' nach='9' betrag='50.0' zeit='Sunday, December 16, 2001 5:02:51 PM CET' /> b = <BuchungCalendarUS von='9' nach='2' betrag='100.0' zeit='Sunday, December 16, 2001 5:02:51 PM CET' /> t = false Beispiel: Mischen von Date und Calendar static void testError() { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); String s = ""; BuchungInterface BuchungInterface BuchungInterface BuchungInterface BuchungInterface sc.println("a sc.println("b sc.println("c sc.println("d sc.println("e = = = = = a b c d e " " " " " = = = = = + + + + + new new new new new BuchungDate(1,9,50.0); BuchungCalendar(9,2,100.0); BuchungCalendarFrance(2,3,50.0); BuchungCalendarUS(3,5,99.0); BuchungCalendarItaly(6,2,15.0); a); b); c); d); e); boolean t; Programmierkurs I (HTML, CSS, Java) - 123 Java, Utilities t = a.vor(b); sc.println("a.vor(b) t = a.vor(c); sc.println("a.vor(c) t = e.vor(c); sc.println("e.vor(c) t = d.vor(a); sc.println("d.vor(a) = " + t); = " + t); = " + t); = " + t); sc.println(); } Ausgabe a = <BuchungDate von='1' nach='1' betrag='50.0' zeit='Sun Dec 16 17:02:51 CET 2001' /> b = <BuchungCalendar von='9' nach='2' betrag='100.0' zeit='Sonntag, 16. Dezember 2001 17.02 Uhr CET' /> c = <BuchungCalendarFrance von='2' nach='3' betrag='50.0' zeit='dimanche 16 décembre 2001 17 h 02 CET' /> d = <BuchungCalendarUS von='3' nach='5' betrag='99.0' zeit='Sunday, December 16, 2001 5:02:51 PM CET' /> e = <BuchungCalendarItaly von='6' nach='2' betrag='15.0' zeit='domenica 16 dicembre 2001 17.02.51 CET' /> a.vor(b) = false a.vor(c) = true e.vor(c) = false d.vor(a) = false ResourceBundle, ListResourceBundle java.util.ResourceBundle dient zur Verknüpfung von Locale und den entsprechenden Texten/Objekten einer Anwendung. public abstract class ResourceBundle extends Object public static final ResourceBundle getBundle(String anwendung) public static final ResourceBundle getBundle(String anwendung, Locale l) public final String getString(String key) public final Object getObject(String key) java.util.ListResourceBundle public abstract class ListResourceBundle extends ResourceBundle protected abstract Object[][] getContents() Aufbau der Resource Namen: baseClassName_language_country_variant BuchungResource, BuchungResource_en, BuchungResource_en_us Beispiel: Einsatz im Buchungssatz import java.util.ListResourceBundle; public class BuchungResource extends ListResourceBundle { public Object[][] getContents() { return texte; } static final Object[][] texte = { { "von", "von" }, { "nach", "nach" }, { "betrag", "betrag" }, { "zeit", "zeit" } }; } Programmierkurs I (HTML, CSS, Java) - 124 Java, Utilities import java.util.ListResourceBundle; public class BuchungResource_en extends ListResourceBundle { public Object[][] getContents() { return texte; } static final Object[][] texte = { { "von", "from" }, { "nach", "to" }, { "betrag", "amount" }, { "zeit", "time" } }; } import java.util.ListResourceBundle; public class BuchungResource_fr extends ListResourceBundle { public Object[][] getContents() { return texte; } static final Object[][] texte = { { "von", "de" }, { "nach", "vers" }, { "betrag", "montant" }, { "zeit", "temps" } }; } import java.util.ListResourceBundle; public class BuchungResource_it extends ListResourceBundle { public Object[][] getContents() { return texte; } static final Object[][] texte = { { "von", "di" }, { "nach", "a" }, { "betrag", "importo" }, { "zeit", "tempo" } }; } import java.util.ResourceBundle; import java.util.Locale; import java.text.DateFormat; public class BuchungCalendarResource extends BuchungCalendar { public BuchungCalendarResource(int von, int nach, double b) { super(von,nach,b); zeitFormat = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL); } public String toString() { ResourceBundle b = ResourceBundle.getBundle("BuchungResource"); String s = "<" + getClass().getName(); s += " " + b.getString("von") + "='" + vonKonto + "'"; s += " " + b.getString("nach") + "='" + nachKonto + "'"; s += " " + b.getString("betrag") + "='" + betrag + "'"; s += " " + b.getString("zeit") + "='" + zeitFormat.format(zeitStempel.getTime()) + "'"; s += " />"; return s; } } Programmierkurs I (HTML, CSS, Java) - 125 Java, Utilities Test Programm: static void testCalendarResource() { Screen sc = new Screen(); KeyBoard kb = new KeyBoard(); String s = ""; BuchungInterface a = new BuchungCalendarResource(1,9,50.0); sc.println("a = " + a); Locale.setDefault( Locale.FRANCE ); BuchungInterface b = new BuchungCalendarResource(9,2,100.0); sc.println("b = " + b); Locale.setDefault( Locale.US ); BuchungInterface c = new BuchungCalendarResource(3,4,99.0); sc.println("c = " + c); Locale.setDefault( Locale.ITALY ); BuchungInterface d = new BuchungCalendarResource(5,2,130.0); sc.println("d = " + d); Locale.setDefault( Locale.GERMANY ); BuchungInterface e = new BuchungCalendarResource(4,7,60.0); sc.println("e = " + e); boolean t; t = a.vor(b); sc.println("a.vor(b) t = a.vor(c); sc.println("a.vor(c) t = e.vor(c); sc.println("e.vor(c) t = d.vor(a); sc.println("d.vor(a) = " + t); = " + t); = " + t); = " + t); sc.println(); } Ausgabe a = <BuchungCalendarResource b = <BuchungCalendarResource c = <BuchungCalendarResource d = <BuchungCalendarResource e = <BuchungCalendarResource a.vor(b) = false a.vor(c) = false e.vor(c) = false d.vor(a) = false von='1' nach='9' betrag='50.0' zeit='Sonntag, 16. Dezember 2001 17.02 Uhr CET de='9' vers='2' montant='100.0' temps='dimanche 16 décembre 2001 17 h 02 CET' from='3' to='4' amount='99.0' time='Sunday, December 16, 2001 5:02:51 PM CET' di='5' a='2' importo='130.0' tempo='domenica 16 dicembre 2001 17.02.51 CET' / von='4' nach='7' betrag='60.0' zeit='Sonntag, 16. Dezember 2001 17.02 Uhr CET Beispiel: Buchungen mit Konten und BuchungCalendarResource import java.util.Vector; import java.util.Iterator; public class KontenTest { public static void main(String[] args) { testBuchung(); } static void testBuchung() { Screen sc = new Screen(); Programmierkurs I (HTML, CSS, Java) - 126 Java, Utilities Konten konten = new Konten(); sc.println("konten = \n" + konten); Vector buchListe = new Vector(); for (int i = 0; i < 10; i++) { int v = (new Double(Math.random()*100.0)).intValue() % 10; int n = (new Double(Math.random()*100.0)).intValue() % 10; if ( v != n ) { double d = Math.floor((new Double(Math.random()*1000.0)).doubleValue()); BuchungInterface b = new BuchungCalendarResource(v,n,d); sc.println("" + b); buchListe.add( b ); } } for (Iterator i = buchListe.iterator(); i.hasNext(); ) { BuchungInterface b = (BuchungInterface) i.next(); int v = b.getVonKonto(); int n = b.getNachKonto(); double d = b.getBetrag(); konten.buche(v, -d); konten.buche(n, d); } sc.println("konten = \n" + konten); } } © Universität Mannheim, Rechenzentrum, 1998-2004. Last modified: Sun Oct 24 13:37:09 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 127 Java, Generik 14. Java, Generik 14.1. Generisches Programmieren • Funktionen höherer Ordnung • Generische Datentypen • Datentypen als Parameter Funktionen höherer Ordnung In der Mathematik Summe_{i=1,n} f(i) oder auch Produkt_{i=1,n} f(i) Zum Beispiel die Lisp-Funktion summe: (define (summe f a b) (if (> a b) 0 (+ (f a) (summe f (+ a 1) b) ) ) ) (define (id x) x) (define (sqr x) (* x x)) (summe id 1 4) 10 (summe sqr 1 4) 30 Lösung in Java Mit einem Interface und public interface SummenFunktion { public double f(int i); } public class Summation { double summe( SummenFunktion sf, int a, int b ) { double sum = 0.0; for (int i = a; i <= b; i++) sum += sf.f(i); return sum; } } Programmierkurs I (HTML, CSS, Java) - 128 Java, Generik Summation UML Diagramm public class Identitaet implements SummenFunktion { public double f(int i) { return (double) i; } } public class Quadrat implements SummenFunktion { public double f(int i) { double d = (double) i; return d*d; } } public class SummenTest { public static void main(String[] args) { Screen out = new Screen(); Summation s = new Summation(); SummenFunktion sf = null; double sum = 0.0; sf = new Identitaet(); sum = s.summe( sf, 1, 4); Programmierkurs I (HTML, CSS, Java) - 129 Java, Generik out.println("Summe von 0 bis ? von f(i) = i ist " + sum); sf = new Quadrat(); sum = s.summe( sf, 1, 4); out.println("Summe von 0 bis ? von f(i) = i*i ist " + sum); } } Zum Beispiel die Lisp-Funktion operation: (define (operation op init f a b) (if (> a b) init (op (f a) (operation op init f (+ a 1) b) ) ) ) (operation + 0 id 1 4) 10 (operation + 0 sqr 1 4) 30 (operation * 1 id 1 4) 24 (operation * 1 sqr 1 4) 576 Lösung in Java public interface Operation { public double getInit(); public double operation( double x, double y); } Programmierkurs I (HTML, CSS, Java) - 130 Java, Generik Operation UML Diagramm public class OperSum implements Operation { public double getInit() { return 0.0; } public double operation( double x, double y) { return x + y; } } public class OperMult implements Operation { public double getInit() { return 1.0; } public double operation( double x, double y) { return x * y; } } Programmierkurs I (HTML, CSS, Java) - 131 Java, Generik public interface OperationFunktion { public double f(int i); } public class GeneralOperation { Operation oper = null; public GeneralOperation( Operation op ) { oper = op; } public double applyoperation( OperationFunktion of, int a, int b ) { double res = oper.getInit(); for (int i = a; i <= b; i++) res = oper.operation( res, of.f(i)); return res; } } public class OperationTest { public static void main(String[] args) { Screen out = new Screen(); OperationFunktion of = null; double erg = 0.0; Operation sum = new OperSum(); GeneralOperation summe = new GeneralOperation( sum ); of = new Identitaet(); erg = summe.applyoperation( of, 1, 4); out.println("Summe von 0 bis ? von f(i) = i ist " + erg); of = new Quadrat(); erg = summe.applyoperation( of, 1, 4); out.println("Summe von 0 bis ? von f(i) = i*i ist " + erg); Operation prod = new OperMult(); GeneralOperation product = new GeneralOperation( prod ); of = new Identitaet(); erg = product.applyoperation( of, 1, 4); out.println("Produkt von 0 bis ? von f(i) = i ist " + erg); of = new Quadrat(); erg = product.applyoperation( of, 1, 4); out.println("Produkt von 0 bis ? von f(i) = i*i ist " + erg); } } Generische Datentypen Jede Klasse ist Unterklasse von Object. Datentypen, die ganz allgemein über (Basis-)Elementen vom Typ Object definiert sind, heissen generisch. Problem: bei der Verarbeitung muss ggf. zur Laufzeit mit instanceof geprüft werden welchen Datentyp die Objekte tatsächlich haben und mit einem entsprechenden Type-Cast angepasst werden. Programmierkurs I (HTML, CSS, Java) - 132 Java, Generik Zum Beispiel die Klassen in java.util oder die folgende Klasse List. Diese Klasse implementiert Listen ähnlich wie in Scheme/Lisp. public class List { private Object a; // allgemeine Daten private List d; // Referenz auf das nächste ELement /** * Der Konstruktor und alle Objekt-Methoden sind nicht * öffentlich. */ protected List(Object ap, List dp) { a = ap; d = dp; } protected Object car() { return a; } protected List cdr() { return d; } /** * Nur die Klassen-Methoden sind öffentlich. */ public static List cons(Object a, List d) { return new List(a,d); } public static Object car(List n) { //if ( n == null ) return null; return n.car(); } public static List cdr(List n) { //if ( n == null ) return null; return n.cdr(); } /** * toString ist auch öffentlich. */ public String toString() { String s = "("; List t = this; Object a; for (;;) { a = t.car(); if ( a == null ) s += "null"; else s += a.toString(); if ( t.cdr() != null ) { s += " "; t = t.cdr(); } else break; } s += ")"; return s; } ... } List l = List.cons(null,null); l = List.cons(l,l); l = List.cons(l,l); System.out.println("l = " + l); List x = new List(new Integer(2),null); System.out.println("x = " + x); List y = new List(new Double(3.0),null); System.out.println("y = " + y); Programmierkurs I (HTML, CSS, Java) - 133 Java, Generik y = List.cons( new Integer(4), y); System.out.println("y = " + y); List z = null; for (int i = 0; i < 10; i++) { z = List.cons( new Integer(i), z); } System.out.println("z = " + z); l x y y z = = = = = (((null) null) (null) null) (2) (3.0) (4 3.0) (9 8 7 6 5 4 3 2 1 0) Datentypen als Parameter Die Verwendung des allgemeinsten Datentypes Object hat den Nachteil, dass immer Typecasts zu den tatsächlich verwendeten Datentypen notwendig sind. Wird die Sprache so erweitert, dass Datentypen als Parameter möglich sind, können die Programme unter Verwendung Datentyp-Parameter formuliert werden. Bei der Instanziierung von Objekten wird für den Typparameter ein konkreter Datentyp eingesetzt. Die nachträglichen Typecasts entfallen damit. Für Datentypen als Parameter wird meist eine spezielle Syntax verwendet. Der Name des formalen Typparameters wird bei der Definition in spitze Klammern eingeschlossen: public class A<Typname> { ... } private Typname variable; public Typname methodname( Typname a, ...) { ... } In C++ sind Datentyp Parameter durch Klassen-Templates realisiert. Templates wie in C++ sind in Java bis JDK 1.4 nicht vorgesehen, aber voraussichtlich ab JDK 1.5 wird es das geben. Neue Frage: Wie können Einschränkungen für die formalen Typparameter formuliert werden? public class A<Typname implementing Interfaces> { } Ein Beispiel in GJ: public class List<EinTyp> { private EinTyp a; // Daten vom Typ 'EinTyp' private List<EinTyp> d; // Referenz auf das nächste ELement /** * Der Konstruktor und alle Objekt-Methoden sind nicht * öffentlich. */ protected List(EinTyp ap, List dp) { a = ap; d = dp; } protected EinTyp car() { return a; } protected List<EinTyp> cdr() { return d; } ... List<Integer> x = new List<Integer>(new Integer(2),null); System.out.println("x = " + x); List<Double> y = new List<Double>(new Double(3.0),null); System.out.println("y = " + y); // Fehler: kein Integer in Double Liste y = List<Double>.cons( new Integer(4), y); Programmierkurs I (HTML, CSS, Java) - 134 Java, Generik System.out.println("y = " + y); List<Integer> z = null; for (int i = 0; i < 10; i++) { z = List<Integer>.cons( new Integer(i), z); } System.out.println("z = " + z); © Universität Mannheim, Rechenzentrum, 2002-2004. Last modified: Sun Oct 24 13:38:58 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 135 Java Tools 15. Java Tools • Java Konventionen • Java Development Kit (JDK) • Integrierte Entwicklungsumgebungen (IDE) • andere Java Tools • Das Ant Build Tool 15.1. Java Konventionen Warum Konventionen? • Lesbarkeit • Wartbarkeit • für den Author • für Partner oder Nachfolger • wenn Abweichung, dann Konsistent Namensgebung Namen für Wort Bezeichner beginnen mit Beispiele Variablen, Attribute Substantive, Adjektive mit Kleinbuchstaben done, length, rein, raus Konstanten Substantive, Adjektive nur Grossbusstaben ONE, ZERO, BLUE, RED, MIN_WIDTH Methoden Substantive, Adjektive, Verben mit Kleinbuchstaben toString(), print(), multiply(), length Klassen, Interfaces Substantive mit Grossbuchstaben StringBuffer, PrintWriter Pakete Substantive nur Kleinbuchstaben, Worttrennung mit '.' edu.unima.kredel.pk1, edu.cmu.cs.author Schreiben Sie bei Bezeichnern, die aus mehreren Worten bestehen, die ersten Buchstaben der inneren Worte gross: toString, toByte, drawLine, BitString, BigInteger. Benutze die Java Dokumentationskommentare. Benutze konsistente Einrückungen. Methoden: maximal eine Bildschirmseite Code. Dateien/Klassen: maximal 1000 Zeilen Code. Defensiv Programmieren • Rechnen Sie mit Ihrer eigenen Dummheit / Beschränktheit • Denken Sie an Testhilfen: if (debug) { ... } • Plausibilitätsprüfungen: assert( a > 0 ) • Sehen Sie eine Methode zum Auslesen des Objektzustands vor. Programmierkurs I (HTML, CSS, Java) - 136 Java Tools z.B. size(), empty(), full() • Optimieren Sie Programme erst ganz zum Schluss (wenn überhaupt). Weitere Empfehlungen • Minimieren Sie die *-Form in import Statements. • Falls mehrere Implementierungen denkbar sind ist ein Interface angebracht. • Objekt-Variablen sollten nie public deklariert werden. • Initialisieren Sie Variablen immer selbst, verlassen Sie sich nicht auf die Defaults. • public static Variablen sollen auch immer final sein. • Verwenden Sie Logger anstatt System.out.println(): logger.debug("a = " + a), logger.info(.), logger.error(.). • Schreiben Sie sich Unit-Tests. z.B. mit JUnit. 15.2. Java Development Kit (JDK) Basic Tools These tools are the foundation of the Java Development Kit. They are the tools you use to create and build applications. javac The compiler for the Java programming language. java The launcher for Java applications. In this release, a single launcher is used both for development and deployment. The old deployment launcher, jre, is no longer provided. javadoc API documentation generator. Also see Javadoc Enhancements for 1.2 appletviewer Run and debug applets without a web browser. jar Manage Java Archive (JAR) files. jdb The Java Debugger. javah C header and stub generator. Used to write native methods. javap Class file disassembler extcheck Utility to detect Jar conflicts. Remote Method Invocation (RMI) Tools These tools help to create apps that interact over the Web or other network. rmic Generate stubs and skeletons for remote objects. rmiregistry Remote object registry service. rmid RMI activation system daemon. serialver Return class serialVersionUID. Internationalization Tools This tool helps to create localizable apps. Programmierkurs I (HTML, CSS, Java) - 137 Java Tools native2ascii Convert text to Unicode Latin-1. Security Tools These tools help you set security policies on your system and create apps that can work within the scope of security policies set at remote sites. keytool Manage keystores and certificates. jarsigner Generate and verify JAR signatures. policytool GUI tool for managing policy files. Java IDL Tools These tools are used when creating apps that use CORBA to access databases. tnameserv Provides access to the naming service. idltojava Generates .java files that map an OMG IDL interface and enable an application written in the Java programming language to use CORBA functionality. This tool is available for download from the Java IDL web site. Documentation for the idltojava compiler is included in the download. 15.3. Integrierte Entwicklungsumgebungen (IDE) • Projektgenerierung mit Templates • Visuelle GUI-Gestaltung • Visuelle Interaktionsgestaltung • Visuelle Verwaltung der Projektkomponenten (z.B. Klassenbrowser) • Komfortables Debuggen • Komfortable Schnürung von Endprodukten • Code Generierung aus UML Diagrammen Beispiele • Visual Cafe (Symantec) • Visual Age for Java (IBM) ist jetzt Eclipse (ORG), • JBuilder, Kylix (Inprise) • Forte for Java, forte4j war Netbeans (Sun) • JDE im Emacs Editor meist bei (X)Emacs dabei (JDE) • Übersicht von JavaWorld • ArgoUML, Poseidon (Argo, GentleWare) Symantecs Visual Cafe 4.0: Programmierkurs I (HTML, CSS, Java) - 138 Java Tools Eclipse 2.0: Programmierkurs I (HTML, CSS, Java) - 139 Java Tools Forte4Java, Netbeans 3.0: ArgoUML, Poseidon: Programmierkurs I (HTML, CSS, Java) - 140 Java Tools Programmierkurs I (HTML, CSS, Java) - 141 Java Tools 15.4. andere Java Tools Neben den schon genannten Tools gibt es noch eine Reihe weiterer Java Compiler und Interpreter. • Kaffe OpenVM komplette Implementierung von Java unter GPL kommerziell unter Transvirtual • Japhar Open Source Java VM ohne Bibliotheken • jikes Java Compiler in C++ geschrieben von IBM, aber OpenSource • GNU Java gcj Java Compiler und VM von GNU, kann Binaries erzeugen, die ohne VM laufen • Open Runtime Platform (ORP) Programmierkurs I (HTML, CSS, Java) - 142 Java Tools Open Source Implementierung der Java Laufzeitklassen 15.5. Ant Build Tool • Build: Vorbereiten, Compilieren, Ausführen, Archive erstellen, Installieren, Konfigurieren • zur Automation des Build-Vorgangs • kann Make (gnumake, nmake, make) ersetzen • wie Java Plattform unabhängig • Beschreibung als XML-Datei • kennt die Java Sprache • erweiterbar durch eigene Java Klassen build.xml für PK1 Definitionen in build.xml: <?xml version="1.0" encoding="iso-8859-1" ?> <project name="pk1" default="usage" basedir="." > <property <property <property <property name="src" name="build" name="doc" name="test" value="." /> value="." /> value="doc" /> value="test" /> <property name="libs" <property name="log4j" <property name="junit" value="/home/heinz/java/lib" /> value="${libs}/log4j.jar" /> value="${libs}/junit.jar" /> <property name="cp" <property name="version" value="${log4j}:${junit}:." /> value="0.1" /> <target name="vorher" > <!-- set properties DSTAMP, TSTAMP --> <tstamp /> <!-- mkdir dir="${test}" /--> </target> <target name="usage" > <echo message="ant <name> cl='cmd'" <!--echoproperties /--> </target> /> <target name="compile" depends="vorher,depend" > <javac srcdir="${src}" destdir="${build}" Programmierkurs I (HTML, CSS, Java) - 143 Java Tools classpath="${cp}" /> </target> <target name="doc" > <javadoc sourcepath="${src}" destdir="${doc}" private="true" > <fileset dir="." includes="**/*.java" /> </javadoc> </target> <target name="depend" depends="vorher" > <depend srcDir="${src}" destDir="${build}" dump="true" closure="true" > </depend> </target> <target name="test" depends="compile" > <java classname="HalloWelt" classpath="${cp}" fork="yes" /> <java classname="HalloCons" classpath="${cp}" fork="yes" /> </target> <target name="jar" depends="vorher" > <jar jarfile="../jas-${DSTAMP}.jar" > <fileset dir="." includes="**/*.java" /> <fileset dir="." includes="jas-log.html" /> <fileset dir="." includes="build.xml Makefile" <fileset dir="edu/jas" /> </jar> </target> /> <target name="clean" > <delete verbose="true" > <fileset dir="${src}" defaultexcludes="no" includes="**/*~" </delete> </target> /> </project> Aufruf: ant target ant compile ant doc Ergebnis des Compilierens: Buildfile: build.xml vorher: depend: [depend] Deleted 0 out of date files in 0 seconds compile: [javac] Compiling 4 source files to /v04 BUILD SUCCESSFUL Total time: 3 seconds Ergebnis des Erzeugens der Dokumentation: Buildfile: build.xml doc: [javadoc] Generating Javadoc [javadoc] Javadoc execution [javadoc] Loading source file [javadoc] Loading source file [javadoc] Loading source file [javadoc] Loading source file /v04/Konto.java... /v04/ComplexTest.java... /v04/Complex.java... /v04/Card.java... Programmierkurs I (HTML, CSS, Java) - 144 Java Tools [javadoc] Constructing Javadoc information... [javadoc] Standard Doclet version 1.4.2 [javadoc] Building tree for all the packages and classes... [javadoc] Building index for all the packages and classes... [javadoc] Building index for all classes... BUILD SUCCESSFUL Total time: 2 seconds Erzeugte Dokumentation. Aufbau einer Build-Datei Das Projekt <project name="pk1" default="target" > ... </project> genau ein project-Element pro Datei Targets, Ziele/Aufgaben <target name="compile" depends="vorher" > ... </target> die target-Elemente definieren die einzelnen Aufgaben Properties, Konstanten <property name="srcDir" value="." /> die property-Elemente definieren Konstanten, die an anderen Stellen mit ${srcDir}, ${...} verwendet werden können <javac srcdir="${srcDir}" ... /> Es gibt diverse eingebaute Properties, z.B. ant.java.version, ant.file, buildt.compiler Tasks, Kommandos <javac srcdir="${src}" destdir="${build}" classpath="${cp}" /> task-Elemente gibt es für alle eingebauten Kommandos und ausführbaren Programme, zum Beispiel • javac Aufruf des Java Compilers • java Aufruf des Java Interpreters • javadoc zum Erzeugen der Dokumentation • delete zum Löschen von Dateien • jar zum Erzeugen von jar-Archiven • war zum Erzeugen von Web-Archiven • junit Durchführen von Unit-Tests mit Junit Jede Task / Kommando wird über (viele) Attribute und Inhaltselemente gesteuert. Inhaltselemente von Tasks <fileset dir="." includes="**/*.java" /> <fileset dir="${src}" includes="**/*~" defaultexcludes="no" /> mit fileset können Teilmengen von Dateien gebildet werden Programmierkurs I (HTML, CSS, Java) - 145 Java Tools <classpath> <pathelement location="dir/name.ext" /> <pathelement path="p1,p2,p3" /> </classpath> mit dem classpath Element kann der Classpath Stück für Stück aufgebaut werden <patternset id="bezeichner" > definitionen </patternset> patternset mit dem Attribut id dient zum Definieren von (Datei-)Mustern. <patternset refid="bezeichner" /> patternset mit dem Attribut refid dient zur Verwendung eines schon definierten (Datei-)Musters. Verschiedenes Eine XML DTD für die Build-Datei und Ant Version kann man sich mit der Task antstructure erzeugen. © Universität Mannheim, Rechenzentrum, 2000-2004. Last modified: Sun Oct 24 13:47:43 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 146 Extensible Markup Language (XML) 16. Extensible Markup Language (XML) • Einleitung • XML Sprachkonstrukte • XML Anwendungen • Stand und Ausblick 16.1. Einleitung • HTML • SGML • XML • eXtensible Markup Language • W3C Recommendation, Programmierkurs I (HTML, CSS, Java) - 147 Extensible Markup Language (XML) 10. Feb. 1998 • von SGML, TEI, HTML Leuten • Basis für viele Dinge HTML Beschränkungen • nicht erweiterbar • nur einfache Struktur • keine Validierung HTML Beispiel (1) <HTML> <HEAD> <TITLE>Beispiel </TITLE> </HEAD> <BODY> <H1>Überschrift</H1> <P>Ein Paragraph mit Text ...</P> </BODY> </HTML> HTML Beispiel (2) <UL> <LI>Eine ungeordnete <LI>Liste <LI>it verschiedenen <LI>Punkten </UL> • Eine ungeordnete • Liste • mit verschiedenen • Punkten Komplexität von SGML • Metasprache zur Definition von HTML • komplexe Struktur • Definition von optionalen Tags • strenge Validierung • Spezifikation: 200+ Seiten • XML Spezifikation: 40 Seiten SGML Beispiel (1) <!ELEMENT COMPANY - - (NAME?,PRODUCT?) > <!ELEMENT NAME - O (#PCDATA)> <!ELEMENT PRODUCT - - (ITEM*)> <!ELEMENT ITEM - O (#PCDATA)> <!ENTITY ... > <!ATTLIST COMPANY type (non-profit | limited | corp) > Programmierkurs I (HTML, CSS, Java) - 148 Extensible Markup Language (XML) SGML Beispiel (2) <COMPANY type=corp > <NAME>All you want <PRODUCT> <ITEM>Apartments <ITEM>Automobiles <ITEM>... </PRODUCT> </COMPANY> Ansatz von XML • Teilmenge von SGML • einfache Spezifikation • offener Standard • International, Unicode • keine optionalen Tags • Syntax Prüfbar • Validierbar • effizient • verbesserte Links, XLL • Style Sheets, XSL XML im Beispiel Dokument: .xml <?xml version="1.0"?> <!DOCTYPE personals SYSTEM "personal.dtd"> <personals> <person id="H.MARUYAMA" > <name><family>MARUYAMA</family> <given>Hiroshi</given></name> <email>[email protected]</email> <link subordinates=" N.URAMOTO K.TAMURA "/> </person> <person id="N.URAMOTO"> <name><family>URAMOTO</family> <given>Naohiko</given></name> <email>[email protected]</email> <link manager=" H.MARUYAMA"/> </person> <person id="K.TAMURA"> <name> <family>TAMURA</family> <given>Kent</given> </name> Programmierkurs I (HTML, CSS, Java) - 149 Extensible Markup Language (XML) <!-- This URL is mail address.--> <url href="mailto:[email protected]"/> <url href="mailto:[email protected]"/> <link manager="H.MARUYAMA"/> </person> </personals> Description / Definition: .dtd <?xml encoding="US-ASCII"?> <!ELEMENT personals (person)+> <!ELEMENT person (name,email*,url*,link?)> <!ATTLIST person id ID #REQUIRED> <!ELEMENT family (#PCDATA)> <!ELEMENT given (#PCDATA)> <!ELEMENT name (#PCDATA|family|given)*> <!ELEMENT email (#PCDATA)> <!ELEMENT url EMPTY> <!ATTLIST url href CDATA #REQUIRED> <!ELEMENT link EMPTY> <!ATTLIST link manager IDREF #IMPLIED subordinates IDREFS #IMPLIED> XML "Helfer" Programmierkurs I (HTML, CSS, Java) - 150 Extensible Markup Language (XML) • XML-Namespace, Namensräume • XLink, XML Linking Language, Verweise aus XML Dokumenten heraus • XPointer, XML Pointer Language, Zeiger in XML Dokumente hinein • XPath, XML Path Language, Wird in XSLT und XPointer benötigt, Zeichenketten die einen bestimten Teil eines XML Dokuments bezeichnen • XSL, Extensible Stylesheet Language Stildefinitionen • XSLT, XSL Transformatons XML Stiltransformationen • XML Schema: Structures, Datatypes Bedingungen (Constraints) für Dokumentstrukturen und Datentypen Programmierkurs I (HTML, CSS, Java) - 151 Extensible Markup Language (XML) 16.2. XML Sprachkonstrukte • Document Type Definition • "wellformed" XML Dokumente geht ohne DTD • "valid" XML Dokumente nur bezüglich einer DTD • Referenz per URI oder Inline Unterschiede zu HTML • XML verlangt korrekte Schachtelung der Elemente • leere Elemente sind speziell gekennzeichnet • nur ein einziges "root" Element • Attributwerte in Quotes • Entities brauchen eine DTD • Elementnamen sind Case-sensitiv • White-Space im Inhalt ist relevant • mehrere Zeichensätze sind verwendbar • es gibt nur wenige reservierte Zeichen XML Dokument • XML Deklaration <?xml version="1.0" encoding="UTF-8" standalone="no" ?> • Deklaration des Dokumenttyps <!DOCTYPE book SYSTEM fileurl > <!DOCTYPE memo [ ... ] > <!DOCTYPE html PUBLIC bezeichner url > • Dokument-Instanz <book> <head> ... </head> <body> ... </body> </book> Dokumentbeschreibung • Elemente <!ELEMENT name Inhalt > <name> ... </name> • Attribute Programmierkurs I (HTML, CSS, Java) - 152 Extensible Markup Language (XML) <!ATTLIST element AttName AttTyp Default > <element AttName="wert" > • Entities <!ENTITY name wert > &name; <!ENTITY % name wert > %name; • Character Data, CDATA <![CDATA[ dies ist kein <tag/> ]]> • Parsed Character Data, PCDATA Mischung aus CDATA und Elementen • Anweisungen, Processing Instructions <?php ... ?> • Kommentare <!-- ... --> • Leerraum, White-Space ist im Inhalt signifikant Inhaltsbeschreibung, Content Model Spec • Folgen (from, to, subject, message, signature) • Auswahl (para|list|image) • Wiederholungsoperatoren • + einmal oder mehr • * nullmal oder mehr • ? nullmal oder einmal • beliebiger Inhalt (#PCDATA) • beliebige Zusammensetzungen (head, (p|list|image)*, div+, (#PCDATA|em|strong)) • leeres Element EMPTY • beliebiges Element ANY Programmierkurs I (HTML, CSS, Java) - 153 Extensible Markup Language (XML) Attributbeschreibung • Attribut Typ • CDATA Zeichenketten • ID Bezeichner • IDREF Verweis auf Bezeichner • IDREFS Folge von IDREF • ENTITY • ENTITIES Folge von ENTITYs • NMTOKEN • NMTOKENS Folge von NMTOKENs • ENUMERATION Aufzählung von Werten • NOTATION Festlegung von Wertformaten • (EN|FR|GR) Enumeration, Aufzählung • Attribut Default • #IMPLIED wird von der Anwendung erkannt • #REQUIRED muss angegeben werden • #FIXED wert fester Wert • wert Defaultwert • Beispiel jahr lang bez href #FIXED (EN|FR|GR) ID CDATA "2000" "EN" #IMPLIED #REQUIRED Beispiel Beschreibung des Dokumententyps <?xml encoding="US-ASCII"?> <!ELEMENT personals (person)+> <!ELEMENT person (name,email*,url*,link?)> <!ATTLIST person id ID #REQUIRED> <!ELEMENT family (#PCDATA)> <!ELEMENT given (#PCDATA)> <!ELEMENT name (#PCDATA|family|given)*> <!ELEMENT email (#PCDATA)> <!ELEMENT url EMPTY> <!ATTLIST url href CDATA #REQUIRED> <!ELEMENT link EMPTY> <!ATTLIST link manager IDREF #IMPLIED subordinates IDREFS #IMPLIED> XML Dokument entsprechend dieser DTD <?xml version="1.0"?> <!DOCTYPE personals SYSTEM "personal.dtd"> Programmierkurs I (HTML, CSS, Java) - 154 Extensible Markup Language (XML) <personals> ... <person id="K.TAMURA"> <name> <family>TAMURA</family> <given>Kent</given> </name> <!-- This URL is mail address.--> <url href="mailto:[email protected]"/> <url href="mailto:[email protected]"/> <link manager="H.MARUYAMA"/> </person> </personals> Validierung Überprüfung ob der Inhalt eines XML Dokumentes einer gegebenen DTD entspricht. Die Java Klassen zur Verarbeitung von XML-Daten gehören ab J2SDK 1.4 standartmässig zum Lieferumfang. Bis zum J2SDK 1.3 muss einzusätzliches Softwarepaket installiert werden. Zur Überprüfung benutzen wir Shell-Scripte. JDK 1.4 und die xercesSamples.jar von xml.apache.org valid (JDK 1.4 Version): #!/bin/sh VALIDPATH="/home/.../java/lib/xercesSamples.jar" export CLASSPATH="$VALIDPATH:$CLASSPATH" /usr/java/j2sdk1.4.1_01/bin/java sax.Counter -p org.apache.crimson.parser.XMLReaderImpl -v $* valid.bat (JDK 1.4 Version): set VALIDPATH=u:\xerces\xercesSamples.jar set CLASSPATH=%VALIDPATH%;%CLASSPATH% java sax.Counter -p org.apache.crimson.parser.XMLReaderImpl -v %1 Hilfe: usage: java sax.Counter (options) uri ... options: -p name -x number -n | -N -np | -NP -v -s | -V | -S -f | -F -dv | -DV -m | -M -t | -T --rem text -h Select parser by name. Select number of repetitions. Turn on/off namespace processing. Turn on/off namespace prefixes. NOTE: Requires use of -n. Turn on/off validation. Turn on/off Schema validation support. NOTE: Not supported by all parsers. Turn on/off Schema full checking. NOTE: Requires use of -s and not supported by all parsers. Turn on/off dynamic validation. NOTE: Requires use of -v and not supported by all parsers. Turn on/off memory usage report Turn on/off "tagginess" report. Output user defined comment before next parse. This help screen. Verwendung: valid datei.xhtml Programmierkurs I (HTML, CSS, Java) - 155 Extensible Markup Language (XML) Alternativ können Sie die Klasse Counter.java selbst kompilieren und wie gewohnt benutzen: java Counter -v datei.xhtml 16.3. XML Anwendungen in Wissenschaft und EDV • SVG Scalable Vector Graphics, Vektorgrafik • SMIL Synchronized Multimedia Integration Language • CML Chemical Markup Language • MML Mathematical Markup Language • RDF Resource Description Framework PICS, CDF, CRP • OSD Open Software Distribution im E-Commerce und Finanzwirtschaft • OASIS, Organization for the Advancement of Structured Information Standards • OFX, Open Financial Exchange • CommerceNet, EDI B2B, e-Commmerce Framework, EDI via XML • Ariba - cXML, Transaktionen: Aufträge, Rechnungen, Änderungsaufträge • finXML, XML für Finanzmärkte, Zinssätze, Währungsumtausch, Bonds, Geldmärkte, Anlagen, Optionen • Acord, XML Standards für die Versicherungswirtschaft • Rosettanet, IT supply chain alignment, server-to-server business exchange • OBI, Open Buying Initiative • Open Travel Alliance • Open Trading Protocol • Open Financial Excange 16.4. Stand und Ausblick XML Tools • SAX Simple API for XML • XML4J XML-Parser in Java von IBM, mit DTD und DOM1, ist in Xerces aufgegangen • msxml XML-Parser in Java von Microsoft, mit DOM1 ohne DTD • Xalan, Xerces Tools der Apache XML Aktivitäten • Koala XSL Processor, wird nicht mehr weiter entwickelt Programmierkurs I (HTML, CSS, Java) - 156 Extensible Markup Language (XML) • Lotus XSL Processor, ist in Xalan aufgegangen Stand der Entwicklung 26. April 2004 • XML 1.0, W3C Recommendation, 10. Feb. 1998 Second Edition, 6. October 2000 • XML 1.1, W3C Recommendation, 4. Feb. 2004 Last edited 15. April 2004 Änderungen bezüglich der Zeichensätze Unicode, UTF-8, UTF-16 • XSL Transormations (XSLT) 1.0, W3C Recommendation, 16. Nov. 1999 • XML Path Language (XPath) 1.0, W3C Recommendation, 16. Nov. 1999 • XML Names, Namespaces in XML W3C Recommendation, 17. Jan. 1999 • Associating Style Sheets with XML documents W3C Recommendation, 29. June 1999 • XSL 1.0, (jetzt nur Formatting) W3C Recommendation, 15. Oktober 2001 • XML Linking Language (XLink), W3C Recommendation, 2. Juni 2001 • XML Base (XBase), W3C Recommendation, 27. June 2001 • XML Pointer Language (XPointer), W3C Recommendation, 25 March 2003 • XML Schema, Part 1 Structures, Part 2 Datatypes, W3C Recommendation, 2. Mai 2001 • XML Protocol, SOAP SOAP 1.1, W3C Note, 8. May 2001 SOAP 1.2, W3C Recommendation, 24. Juni 2003 • XML Query 1.0 and XPath 2.0 Data Model, W3C Working Draft, 12. November 2003 • XML Path Language (XPath) 2.0, W3C Working Draft, 12. November 2003 • XML Signature Syntax and Processing, W3C Recommendation, 12. February 2002, IETF Request for Comments: 3275, March 2002 • Canonical XML 1.0, W3C Recommendation, 15 March 2001 • XML Information Set (Second Edition), W3C Recommendation, 4. February 2004 • XML Forms 1.0, W3C Recommendation, 14. Oktober 2003 • Web Services Description Language (WSDL) 1.2, W3C Working Draft, 11. Juni 2003 • Web Ontology Language (OWL) 1.0, W3C Recommendation, 10. Februar 2004 • RDF Schema, Programmierkurs I (HTML, CSS, Java) - 157 Extensible Markup Language (XML) W3C Recommendation, 10. Februar 2004 • RDF Site Summary (RSS) 1.0, (RSS WG) Recommendation, 9. Dezember 2000 © Universität Mannheim, Rechenzentrum, 1998-2004. Last modified: Sat Jun 12 11:52:23 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 158 Java API for XML Processing (JAXP) 17. Java API for XML Processing (JAXP) Parser = Programm zum Einlesen von Dokumenten entsprechend einer Syntax-Definition. Das Ergebnis ist eine interne Datenstruktur. • Lexikalische Analyse: Scanner z.B. LEX • Syntaktische Analyse: z.B YACC oder GNU BISON, bei XML Wohlgeformtheit feststellen • Semantische Analyse: auch YACC / BISON, bei XML Gültigkeit bez. DTD feststellen Ausblick: Java API for XML Binding (JAXM) Generation der Java Klassen direkt aus einer DTD. 17.1. DOM und SAX Parsers • DOM = Document Object Model, W3C • erzeugt (Java-)Objekt aus XML Datei, erlaubt Manipulation dieser Objekte • DocumentBuilder • DocumentBuilderFactory • SAX = Simple API for XML, XML-Developer • Ereignisse (wie startElement) werden durch Handler verarbeitet • SAXParser • SAXParserFactory • SAX 2 mit Namespace Unterstützung Vorteile: • DOM liefert fertiges Dokumenten Objekt • SAX ist sehr effizient und braucht wenig Speicher Nachteile: • DOM ist ineffizient und braucht viel Speicher • bei DOM muss evtl. die Datenstruktur doppelt erzeugt werden Programmierkurs I (HTML, CSS, Java) - 159 Java API for XML Processing (JAXP) • bei SAX keine Garantie, dass gültige Dokumente entstehen • Entwicklung der SAX Handler für komplizierte DTDs schwer DOM Parser • Apache Xerces: org.apache.xerces.parser.DOMParser • im JDK ab 1.4 als: javax.xml.parsers.DocumentBuilder und javax.xml.parsers.DocumentBuilderFactory DocumentBuilderFactory javax.xml.parsers.DocumentBuilderFactory dient der Erzeugung eines DOM Parsers javax.xml.parsers.DocumentBuilder. protected DocumentBuilderFactory() public static newInstance() public DocumentBuilder newDocumentBuilder() public boolean isValidating() public void setValidating(boolean) public boolean isExpandEntityReferences() public void setExpandEntityReferences(boolean) DocumentBuilder javax.xml.parsers.DocumentBuilder dient dem Parsen, d.h. dem Einlesen und Aufbau eines org.w3c.dom.Document. protected DocumentBuilder() public Document newDocument() public public public public Document Document Document Document parse(File f) parse(InputStream is) parse(InputSource is) parse(String uri) public boolean isValidating() public void setErrorHandler(ErrorHandler) DOMLeser: import import import import import import import import javax.xml.parsers.DocumentBuilderFactory; javax.xml.parsers.DocumentBuilder; javax.xml.parsers.ParserConfigurationException; org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.Element; java.io.IOException; org.xml.sax.SAXException; public class DOMLeser { public static void main(String[] args) { DocumentBuilderFactory pfac = DocumentBuilderFactory.newInstance(); DocumentBuilder parser = null; try { pfac.setValidating(true); Programmierkurs I (HTML, CSS, Java) - 160 Java API for XML Processing (JAXP) // pfac.setCoalescing(true); pfac.setExpandEntityReferences(false); parser = pfac.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } Document doc = null; String uri = "datei.xml"; try { doc = parser.parse(uri); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Screen sc = new Screen(); sc.println("doc("+ doc.getClass().getName() + ") = " + doc ); DOMSchreiber dw = new DOMSchreiber(); sc.println("document:\n"); dw.printNode(doc); dw.flush(); dw.close(); } } DOM Node Die Werte von nodeName, nodeValue, und attributes hängen wie folgt vom Knotentyp ab: Interface nodeName nodeValue Attr name of attribute value of attribute CDATASection "#cdata-section" content of the CDATA Section Comment "#comment" content of the comment Document "#document" null DocumentFragment "#document-fragment" null DocumentType document type name null Element tag name null Entity entity name null EntityReference name of entity referenced null Notation notation name null ProcessingInstruction target entire content excluding the target Text "#text" content of the text node Siehe Document Object Model (DOM) Level 2 Core Specification. DOMSchreiber: import import import import import org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.NodeList; org.w3c.dom.NamedNodeMap; org.w3c.dom.Element; Programmierkurs I (HTML, CSS, Java) - 161 Java API for XML Processing (JAXP) import import import import import import import org.w3c.dom.Text; org.w3c.dom.Comment; org.w3c.dom.EntityReference; org.w3c.dom.DocumentType; java.io.IOException; java.io.PrintWriter; org.xml.sax.SAXException; public class DOMSchreiber { PrintWriter pw = null; public DOMSchreiber() { pw = new Screen(); } public DOMSchreiber(PrintWriter p) { pw = p; } public void printNode(Node node) { switch ( node.getNodeType() ) { case Node.ELEMENT_NODE: printElement( (Element)node ); break; case Node.ATTRIBUTE_NODE: printAttributes( (NamedNodeMap)node ); break; case Node.TEXT_NODE: printText( (Text)node ); break; case Node.CDATA_SECTION_NODE: printCData( (Text)node ); break; case Node.PROCESSING_INSTRUCTION_NODE: printPI( node ); break; case Node.COMMENT_NODE: printComment( (Comment)node ); break; case Node.DOCUMENT_TYPE_NODE: printDoctype( (DocumentType)node ); break; case Node.DOCUMENT_NODE: printDocument( (Document)node ); break; case Node.ENTITY_REFERENCE_NODE: printEntityReference( (EntityReference)node ); break; default: pw.println("<!-- " + node + " -->"); } } public void printElement(Element el) { String name = el.getNodeName(); pw.print("<" + name ); printAttributes( el.getAttributes() ); NodeList nl = el.getChildNodes(); if ( ( nl == null ) || ( nl.getLength() == 0 ) ) { pw.print(" />"); return; } pw.print(">"); for (int i = 0; i < nl.getLength(); i++ ){ printNode(nl.item(i)); } pw.print("</" + name + ">"); } Programmierkurs I (HTML, CSS, Java) - 162 Java API for XML Processing (JAXP) public void printAttributes(NamedNodeMap at) { if ( at == null ) return; for ( int i = 0; i < at.getLength(); i++ ){ Node an = at.item(i); pw.print(" " + an.getNodeName() + "=\""); pw.print(an.getNodeValue() + "\""); } } public void printText(Text tx) { pw.print( tx.getData() ); } public void printEntityReference(EntityReference er) { pw.print("&" + er.getNodeName() + ";" ); } public void printComment(Comment c) { pw.print("<!--"); pw.print( c.getData() ); pw.print("-->"); } public void printDoctype(DocumentType d) { pw.print("<!DOCTYPE "); pw.print( d.getName() ); String pid = d.getPublicId(); if ( pid != null ) { pw.print(" PUBLIC \"" + pid + "\"\n } else { pw.print(" SYSTEM " ); } pw.print("\"" + d.getSystemId() + "\" "); pw.println(">"); } "); public void printCData(Text tx) { pw.print("<![CDATA[ "); pw.print( tx.getNodeValue() ); pw.print("]]>"); } public void printDocument(Document doc) { printNode( doc.getDoctype() ); printNode( doc.getDocumentElement() ); } public void printPI(Node pi) { pw.print("<?" + pi.getNodeName() ); pw.print(" " + pi.getNodeValue() + "?>" ); } public void flush() { pw.flush(); } public void close() { pw.close(); } } datei.xhtml: Programmierkurs I (HTML, CSS, Java) - 163 Java API for XML Processing (JAXP) <?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Titel</title> <?php $a=9; function yyy(a) { if ( a > 2 ) { print("<p>nonsense</p>"); } } ?> <!-- funktions definitionen --> <script type="text/javascript" language="JavaScript"> <![CDATA[ function xxx(a) { if ( a > 2 ) { document.write("<p>nonsense</p>"); } } ]]> </script> </head> <body bgcolor="white"> <h1>Überschrift A</h1> <p align="center">Paragraph mit <em>Hervorhebung</em> und einem <br /> Zeilenumbruch. </p> <ul> <li>Listen Element</li> <li>Entity Element &abc; </li> </ul> <h1>Überschrift B</h1> <p>Text eines zweiten Paragraphen mit <strong>Hervorhebung</strong> ohne Zeilenumbruch. </p> <h1 count="10">Überschrift C</h1> <p>Text eines dritten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> <h1>Überschrift D</h1> <p>Text eines vierten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> </body> </html> Ausgabe: Warning: validation was turned on but an org.xml.sax.ErrorHandler was not set, which is probably not what is desired. Parser will use a default ErrorHandler to print the first 10 errors. Please call the 'setErrorHandler' method to fix this. Error: URI=datei.xhtml Line=41: Attribute "count" must be declared for element type "h1". doc(org.apache.xerces.dom.DeferredDocumentImpl) = [#document: null] document: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd" > <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Titel</title> <?php $a=9; function yyy(a) { if ( a > 2 ) { print("<p>nonsense</p>"); Programmierkurs I (HTML, CSS, Java) - 164 Java API for XML Processing (JAXP) } } ?> <!-- funktions definitionen --> <script language="JavaScript" type="text/javascript"> <![CDATA[ ]]> </script> </head> <body bgcolor="white"> <h1>Überschrift A</h1> <p align="center">Paragraph mit <em>Hervorhebung</em> und einem <br clear="none" /> Zeilenumbruch. </p> <ul> <li>Listen Element</li> <li>Entity Element &abc; </li> </ul> <h1>Überschrift B</h1> <p>Text eines zweiten Paragraphen mit <strong>Hervorhebung</strong> ohne Zeilenumbruch. </p> <h1 count="10">Überschrift C</h1> <p>Text eines dritten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> <h1>Überschrift D</h1> <p>Text eines vierten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> </body> </html> DOMUtil: import import import import org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.NodeList; org.w3c.dom.Element; public class DOMUtil { private static int inc = 0; public static void addIdent(Node node, String prefix) { switch ( node.getNodeType() ) { case Node.ELEMENT_NODE: addElementIdent( (Element)node, prefix ); break; case Node.DOCUMENT_NODE: addElementIdent( ((Document)node).getDocumentElement(), prefix ); break; default: ; } } public static void addElementIdent(Element el, String prefix) { el.setAttribute("id", "#"+prefix+inc); el.setAttribute("name", "#"+prefix+inc++); NodeList nl = el.getChildNodes(); if ( ( nl == null ) || ( nl.getLength() == 0 ) ) { return; } for (int i = 0; i < nl.getLength(); i++ ){ Node c = nl.item(i); addIdent(c, prefix); } } } Programmierkurs I (HTML, CSS, Java) - 165 Java API for XML Processing (JAXP) Anwendung: // ... wie oben DOMUtil.addIdent(doc,"hk"); sc.println("document:\n"); dw.printNode(doc); dw.flush(); sc.println(); Ausgabe: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd" > <html id="#hk0" name="#hk0" xmlns="http://www.w3.org/1999/xhtml"> <head id="#hk1" name="#hk1"> <title id="#hk2" name="#hk2">Titel</title> <?php $a=9; function yyy(a) { if ( a > 2 ) { print("<p>nonsense</p>"); } } ?> <!-- funktions definitionen --> <script id="#hk3" language="JavaScript" name="#hk3" type="text/javascript"> <![CDATA[ ]]> </script> </head> <body bgcolor="white" id="#hk4" name="#hk4"> <h1 id="#hk5" name="#hk5">Überschrift A</h1> <p align="center" id="#hk6" name="#hk6">Paragraph mit <em id="#hk7" name="#hk7">Hervorhebung</em> und einem <br clear="none" id="#hk8" name="#hk8" /> Zeilenumbruch. </p> <ul id="#hk9" name="#hk9"> <li id="#hk10" name="#hk10">Listen Element</li> <li id="#hk11" name="#hk11">Entity Element &abc; </li> </ul> <h1 id="#hk12" name="#hk12">Überschrift B</h1> <p id="#hk13" name="#hk13">Text eines zweiten Paragraphen mit <strong id="#hk14" name="#hk14">Hervorhebung</strong> ohne Zeilenumbruch. </p> <h1 count="10" id="#hk15" name="#hk15">Überschrift C</h1> <p id="#hk16" name="#hk16">Text eines dritten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> <h1 id="#hk17" name="#hk17">Überschrift D</h1> <p id="#hk18" name="#hk18">Text eines vierten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> </body> </html> SAX Parser • Apache Xerces: org.apache.xerces.parser.SAXParser • im JDK ab 1.4 als: javax.xml.parsers.SAXParser und javax.xml.parsers.SAXParserFactory SAXParserFactory javax.xml.parsers.SAXParserFactory dient der Erzeugung eines SAX Parsers javax.xml.parsers.SAXParser. Programmierkurs I (HTML, CSS, Java) - 166 Java API for XML Processing (JAXP) protected SAXParserFactory() public static newInstance() public SAXParser newSAXParser() boolean isValidating() void setValidating(boolean) boolean isExpandEntityReferences() void setExpandEntityReferences(boolean) boolean isNamespaceAware() void setNamespaceAware(boolean) SAXParser javax.xml.parsers.SAXParser dient dem Parsen, d.h. dem Einlesen und Verarbeiten der gefundenen XML Konstrukte. protected SAXParser() public public public public void void void void parse(File f, DefaultHandler dh) parse(InputStream is, DefaultHandler dh) parse(InputSource is, DefaultHandler dh) parse(String uri, DefaultHandler dh) public boolean isValidating() public abstract void setProperty(String name, Object value) public abstract Object getProperty(String name) SAXLeser: import import import import import import javax.xml.parsers.SAXParserFactory; javax.xml.parsers.SAXParser; javax.xml.parsers.ParserConfigurationException; java.io.IOException; org.xml.sax.SAXException; org.xml.sax.helpers.DefaultHandler; public class SAXLeser { public static void main(String[] args) { SAXParserFactory pfac = SAXParserFactory.newInstance(); SAXParser parser = null; try { pfac.setValidating(true); pfac.setNamespaceAware(true); parser = pfac.newSAXParser(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } Screen sc = new Screen(); String uri = "datei.xhtml"; DefaultHandler dh = new SAXSchreiber(sc); try { parser.parse(uri,dh); } catch (SAXException e) { e.printStackTrace(); } Programmierkurs I (HTML, CSS, Java) - 167 Java API for XML Processing (JAXP) catch (IOException e) { e.printStackTrace(); } } } DefaultHandler aus org.xml.sax.helpers, implementiert die Interfaces ContentHandler, DTDHandler, EntityResolver und ErrorHandler: public void startDocument() public void endDocument() public void startElement(String nameuri, String local, String quali, Attributes attrs) public void endElement(String nameuri, String local, String quali) public void characters(char ch[], int start, int length) public void ignorableWhitespace(char ch[], int start, int length) public void processingInstruction(String target, String data) public void warning(SAXParseException ex) public void error(SAXParseException ex) public void fatalError(SAXParseException ex) public InputSource resolveEntity(String publicId, String systemId) public void notationDecl(String name, String publicId, String systemId) SAXSchreiber: import import import import import import import java.io.IOException; java.io.PrintWriter; org.xml.sax.SAXException; org.xml.sax.SAXParseException; org.xml.sax.Attributes; org.xml.sax.InputSource; org.xml.sax.helpers.DefaultHandler; public class SAXSchreiber extends DefaultHandler { PrintWriter pw = null; public SAXSchreiber() { pw = new Screen(); } public SAXSchreiber(PrintWriter p) { pw = p; } public void startDocument() { pw.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); pw.flush(); } public void endDocument() { pw.println(); pw.flush(); } public void startElement(String nameuri, String local, String quali, Attributes attrs) { pw.print('<'); pw.print(local); Programmierkurs I (HTML, CSS, Java) - 168 Java API for XML Processing (JAXP) if (attrs != null) { int len = attrs.getLength(); for (int i = 0; i < len; i++) { pw.print(' '); pw.print(attrs.getQName(i)); pw.print("=\""); pw.print(attrs.getValue(i)); pw.print('"'); } } pw.print('>'); pw.flush(); } public void endElement(String nameuri, String local, String quali) { pw.print("</"); pw.print(local); pw.print('>'); pw.flush(); } public void characters(char ch[], int start, int length) { pw.print( new String(ch, start, length) ); pw.flush(); } public void ignorableWhitespace(char ch[], int start, int length) { characters(ch, start, length); } public void processingInstruction(String target, String data) { pw.print("<?"); pw.print(target); if (data != null && data.length() > 0) { pw.print(' '); pw.print(data); } pw.print("?>"); pw.flush(); } public void warning(SAXParseException ex) { pw.println("\n<!-- [Warning] "+ ex.getSystemId()+": line "+ ex.getLineNumber()+", column "+ ex.getColumnNumber()+":\n"+ ex.getMessage() + " -->"); } public void error(SAXParseException ex) { pw.println("\n<!-- [Error] "+ ex.getSystemId()+": line "+ ex.getLineNumber()+", column "+ ex.getColumnNumber()+":\n"+ ex.getMessage() + " -->"); } public void fatalError(SAXParseException ex) { pw.println("\n<!-- [Fatal Error] "+ ex.getSystemId()+": line "+ ex.getLineNumber()+", column "+ ex.getColumnNumber()+":\n"+ ex.getMessage() + " -->"); } public InputSource resolveEntity(String publicId, String systemId) { pw.println("\n<!-- [resolveEntity] publicId: "+ publicId + ", systemId: " + systemId + " -->" ); Programmierkurs I (HTML, CSS, Java) - 169 Java API for XML Processing (JAXP) boolean dtd = false; boolean pid = false; boolean sid = false; if ( ( publicId != null ) || ( systemId != null ) ) { pid = pid || ( publicId.indexOf("DTD") >= 0 ); pid = pid || ( publicId.indexOf("dtd") >= 0 ); sid = sid || ( systemId.indexOf("DTD") >= 0 ); sid = sid || ( systemId.indexOf("dtd") >= 0 ); } if (pid) { pw.print("<!DOCTYPE ???? " ); pw.print("PUBLIC \"" + publicId + "\""); if (sid) { pw.print(" \"" + systemId + "\""); pw.println(" >"); } } else if (sid) { pw.print("<!DOCTYPE ???? " ); pw.print("SYSTEM \"" + systemId + "\""); pw.println(" >"); } return null; } public void notationDecl(String name, String publicId, String systemId) { pw.println("\n[notationDeclaration] name: " + name + " publicId: "+ publicId + ", systemId: " + systemId ); } } Attributes aus org.xml.sax, AttributesImpl aus org.xml.sax.helpers: interface Attributes int getLength() int getIndex(String qName) int getIndex(String uri, String localName) String getQName(int index) String getLocalName(int index) String getURI(int index) String getValue(int index) String getValue(String qName) String getValue(String uri, String localName) String getType(int index) String getType(String qName) String getType(String uri, String localName) class AttributesImpl plus AttributesImpl() AttributesImpl(Attributes atts) void clear() void removeAttribute(int index) void addAttribute(String uri, String localName, String qName, String type, String value) void addAttribute(int index, String uri, String localName, String qName, String type, String value) void setAttributes(Attributes atts) void setLocalName(int index, String localName) void setQName(int index, String qName) Programmierkurs I (HTML, CSS, Java) - 170 Java API for XML Processing (JAXP) void setType(int index, String type) void setURI(int index, String uri) void setValue(int index, String value) SAXUtil: Nummerieren der h1-Überschriften import import import import import import import import java.io.IOException; java.io.PrintWriter; org.xml.sax.SAXException; org.xml.sax.SAXParseException; org.xml.sax.Attributes; org.xml.sax.InputSource; org.xml.sax.helpers.DefaultHandler; org.xml.sax.helpers.AttributesImpl; public class SAXUtil extends SAXSchreiber { int chapter = 0; boolean insertCounter = false; public SAXUtil() { pw = new Screen(); } public SAXUtil(PrintWriter p) { pw = p; } public void startDocument() { chapter = 0; super.startDocument(); } public void startElement(String nameuri, String local, String quali, Attributes attrs) { if ( !quali.equals("h1") ) { super.startElement(nameuri,local,quali,attrs); pw.flush(); return; } Attributes at = attrs; String cVal = null; if ( at != null ) { cVal = at.getValue("count"); if (cVal == null) { cVal = "" + (++chapter); AttributesImpl ai = new AttributesImpl(at); ai.addAttribute("","","count","",cVal); at = (Attributes) ai; } else { chapter = Integer.parseInt(cVal); } } else { AttributesImpl ai = new AttributesImpl(); cVal = "" + (++chapter); ai.addAttribute("","","count","",cVal); at = (Attributes) ai; } insertCounter = true; super.startElement(nameuri,local,quali,at); } public void characters(char ch[], int start, int length) { String s = new String(ch, start, length); if ( insertCounter ) { s = "Kapitel " + chapter + ". " + s; insertCounter = false; } Programmierkurs I (HTML, CSS, Java) - 171 Java API for XML Processing (JAXP) pw.print( s ); pw.flush(); } public InputSource resolveEntity(String publicId, String systemId) { return null; } public void notationDecl(String name, String publicId, String systemId) { } } Ausgabe für 'datei.xhtml' von oben: <?xml version="1.0" encoding="iso-8859-1"?> <!-- [resolveEntity] publicId: -//W3C//DTD XHTML 1.0 Transitional//EN, systemId: DTD/xhtml1-transitional.d <!DOCTYPE ???? PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd" > <!-- [resolveEntity] publicId: -//W3C//ENTITIES Latin 1 for XHTML//EN, systemId: xhtml-lat1.ent --> <!-- [resolveEntity] publicId: -//W3C//ENTITIES Symbols for XHTML//EN, systemId: xhtml-symbol.ent --> <!-- [resolveEntity] publicId: -//W3C//ENTITIES Special for XHTML//EN, systemId: xhtml-special.ent --> <html> <head> <title>Titel</title> <?php $a=9; function yyy(a) { if ( a > 2 ) { print("<p>nonsense</p>"); } } ?> <script type="text/javascript" language="JavaScript"> function xxx(a) { if ( a > 2 ) { document.write("<p>nonsense</p>"); } } </script> </head> <body bgcolor="white"> <h1>Überschrift A</h1> <p align="center">Paragraph mit <em>Hervorhebung</em> und einem <br clear="none"></br> Zeilenumbruch. </p> <ul> <li>Listen Element</li> <li>Entity Element &abc; </li> </ul> <h1>Überschrift B</h1> <p>Text eines zweiten Paragraphen mit <strong>Hervorhebung</strong> ohne Zeilenumbruch. </p> <!-- [Error] datei.xhtml: line 41, column 16: Attribute "count" must be declared for element type "h1". --> <h1 count="10">Überschrift C</h1> <p>Text eines dritten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> <h1>Überschrift D</h1> <p>Text eines vierten Paragraphen ohne Programmierkurs I (HTML, CSS, Java) - 172 Java API for XML Processing (JAXP) Hervorhebungen und ohne Zeilenumbruch. </p> </body> </html> SAXNummer: import import import import import import javax.xml.parsers.SAXParserFactory; javax.xml.parsers.SAXParser; javax.xml.parsers.ParserConfigurationException; java.io.IOException; org.xml.sax.SAXException; org.xml.sax.helpers.DefaultHandler; public class SAXNummer { public static void main(String[] args) { SAXParserFactory pfac = SAXParserFactory.newInstance(); SAXParser parser = null; try { // pfac.setValidating(true); pfac.setNamespaceAware(true); parser = pfac.newSAXParser(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } Screen sc = new Screen(); String uri = "datei.xhtml"; DefaultHandler dh = new SAXUtil(sc); try { parser.parse(uri,dh); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } Ausgabe für 'datei.xhtml' von oben: <?xml version="1.0" encoding="iso-8859-1"?> <html> <head> <title>Titel</title> <?php $a=9; function yyy(a) { if ( a > 2 ) { print("<p>nonsense</p>"); } } ?> <script type="text/javascript" language="JavaScript"> function xxx(a) { if ( a > 2 ) { document.write("<p>nonsense</p>"); } } Programmierkurs I (HTML, CSS, Java) - 173 Java API for XML Processing (JAXP) </script> </head> <body bgcolor="white"> <h1 count="1">Kapitel 1. Überschrift A</h1> <p align="center">Paragraph mit <em>Hervorhebung</em> und einem <br clear="none"></br> Zeilenumbruch. </p> <ul> <li>Listen Element</li> <li>Entity Element &abc; </li> </ul> <h1 count="2">Kapitel 2. Überschrift B</h1> <p>Text eines zweiten Paragraphen mit <strong>Hervorhebung</strong> ohne Zeilenumbruch. </p> <h1 count="10">Kapitel 10. Überschrift C</h1> <p>Text eines dritten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> <h1 count="11">Kapitel 11. Überschrift D</h1> <p>Text eines vierten Paragraphen ohne Hervorhebungen und ohne Zeilenumbruch. </p> </body> </html> © Universität Mannheim, Rechenzentrum, 1998-2004. Last modified: Sun Oct 24 13:40:44 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 174 Literatur 18. Literatur Brewing Java: A Tutorial E. Harold, 2001, URL http://sunsite.informatik.rwth-aachen.de/javafaq/javatutorial.html Cascading Style Sheets H. Lie & B. Bos, Addison-Wesley, 1997. Cascading Style Sheets S. Münz & A. Keßler, Data Becker, 2001. Cascading Style Sheets, level 1 (CSS1) Specification W3C Recommendation, 1996, URL http://www.w3.org/TR/REC-CSS1 Cascading Style Sheets, level 2 (CSS2) Specification W3C Recommendation, 1998, URL http://www.w3.org/TR/REC-CSS2 Cygwin = GNU + Cygnus + Windows Portierung der GNU Tools auf Windows, URL http://www.cygwin.com/ Cygwin: A Free Win32 Porting Layer for UNIX® Applications USENIX Windows NT Workshop Proceedings, 1998, URL http://www.cygwin.com/usenix-98/cygwin.html Extensible Markup Language (XML) 1.0 Specifikation W3C Recommendation, 1998, URL http://www.w3.org/TR/REC-xml Einführung in die objektorientierte Programmierung mit Java E.-E. Doberkat & S. Dißmann, Oldenburg, 2002. Einführung in die Informatik - Objektorientiert mit Java W. Küchlin & A. Weber, Springer, 2003 (2nd ed.). Einführung in Java F. Jobst, Hanser, 2001. Einführung in Java Ch. Wolff, Teubner, 1999. GNU Java (GCJ) GNU Compiler und VM für Java, URL http://gcc.gnu.org/java/ Grundkurs Java D. Abts, Vieweg, 2002. Grundkurs Programmieren in Java, 2 Bände D. Ratz & J. Scheffler & D. Seese, Hanser, 2002. HTML 4.0 Specification W3C Recommendation, 1998, URL http://www.w3.org/TR/REC-html40/ HTML Ratgeber H. Bonin, Hanser, 1996. HTML Tidy D. Raggett, W3C, 1999, URL http://www.w3.org/People/Raggett/tidy/. Japhar Open Source Java VM, URL http://www.japhar.org/ Java 2 RRZN, Uni Hannover, 2001. Java Sun, 1998-2000, URL http://www.javasoft.com/ oder http://java.sun.com/ Java als erste Programmiersprache J. Goll & C. Weiß & F. Müller, Teubner, 2001. Programmierkurs I (HTML, CSS, Java) - 175 Literatur Java Einführung H. Partl, Uni-Bodenkultur Wien, 2001, URL http://www.boku.ac.at/javaeinf/ Java Apache Apache Software Foundation, URL http://java.apache.org/ Java Enterprise in a Nutshell D. Flanagan & J. Farley & W. Crawford & K. Magnusson, O'Reilly, 20011 Java Foundation Classes in a Nutshell D. Flanagan, O'Reilly, 2000 Java in a Nutshell D. Flanagan, O'Reilly, 1997 (2nd ed.), Deutsche Ausgabe, 2000 (3rd ed.) 2002 (4th ed.) Java Programmierhandbuch und Referenz S. Middendorf & R. Singer, dpunkt, 1999 (2nd ed.), 2002 (3rd ed.). Java - Eine Einführung M. Schader & L. Schmidt-Thieme, Springer, 2000 (3nd ed.). Java-Entwicklung mit Eclipse 3 B. Daum, dpunkt, 2004 (2nd ed.). Java Server Pages Sun, 2000, URL http://java.sun.com/products/jsp/tomcat/ oder Apache Software Foundation, 2000, URL http://jakarta.apache.org/ Java Servlets Sun, 2000, URL http://java.sun.com/products/servlets/ Java Software Engineering unter Linux O. Böhm, SuSE Press, 2002. The Java Tutorial Sun, URL http://java.sun.com/docs/books/tutorial/ Java und XML B. McLaughlin, O'Reilly, 2000. jikes Open Source Java Compiler von IBM, URL http://www.jikes.org/ Kaffe OpenVM URLs http://www.kaffe.org/, http://www.transvirtual.com/ Lehrbuch der Programmierung mit Java K. Echtle & M. Goedicke, dpunkt, 2000. Lehrbuch Grundlagen der Informatik H. Balzert, Spektrum, 1999. Lynda, Web-Design URL http://www.lynda.com/ Microsoft URL http://www.microsoft.com/ Netscape URL http://www.netscape.com/ Objektorientierte Programmierung in Java O. Rauh, Vieweg, 2000. Online-Tutorial zu HTML (mit CSS) S. Münz, 1998-1999, URL http://www.teamone.de/selfhtml/ Opera Web-Browser 1999, URL http://www.opera.com/ Programmieren in Java Programmierkurs I (HTML, CSS, Java) - 176 Literatur F. Jobst, Hanser, 2002. Programmieren mit Java A. Solymosi & I. Schmiedecke, Vieweg, 2001. Request for Comment (RFC) Online Verzeichnis, 1999, URL http://www.rfc-editor.org/ Sprechen Sie Java? H. Mössenböck, dpunkt, 2001. Style-Guide für Web-Sites 1998, URL http://www.gui-design.de/ Unicode URL http://www.unicode.org/ Die Sprache des Web: HTML 3, HTML 4 R. Tolksdorf, dpunkt, 1995, 1997. Thinking in Java B. Eckel, 2000, URL http://www.mindview.net/Books/TIJ/ UML 2 @ Work M. Hitz & G. Kappel, dpunkt, 2004 (3nd ed.). Unit Tests mit Java J. Link & P. Fröhlich, dpunkt, 2004. Web-Programmierung mit Java und XML M. Knopp & G. Wilhelms, Hanser, 2002. World Wide Web Consortium W3C Homepage, URL http://www.w3.org/ W3C Style Sheet Beispiele W3C, 1997, URL http://www.w3.org/Style/, siehe auch http://www.w3.org/StyleSheets/Core/preview Wilde´s WWW E. Wilde, Springer, 1999, 2002 (2nd ed.). XML Apache Tools Apache Software Foundation, URL http://xml.apache.org/ XHTML 1.0: The Extensible HyperText Markup Language - A Reformulation of HTML 4 in XML 1.0 W3C Recommendation, January 2000, URL http://www.w3.org/TR/xhtml1 XML Resources URL http://www.xml.com/ XML Resources at IBM URL http://www.ibm.com/xml/ © Universität Mannheim, Rechenzentrum, 1998-2005. Last modified: Sat Oct 23 16:30:59 CEST 2004 Programmierkurs I (HTML, CSS, Java) - 177