Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow Einführung in die Informatik - Teil 4 Java-Anwendungen und Zeichenketten Inhalt: 1. Anwendungen versus Applets 2. Die Arbeit mit der IDE 3. NetBeans-Anwendungen entwickeln 3.1 Erzeugen einer neuen leeren Anwendung 3.2 Der Quelltext 3.3 Das Einfügen von Steuerelementen 3.4 Zeichnen 4. Zeichenketten 4.1 Bezug zum Unterricht 4.2 Oberfläche und Ereignisverarbeitung 4.3 Die Erzeugung von GUI-Komponenten 4.4 Die Verarbeitung von Ereignissen 4.5 Eine Anwendung zur Ein- und Ausgabe von Zeichenketten 5. Methoden zur Zeichenkettenverarbeitung 6. Verschlüsselungsverfahren 7. Aufgaben 8. Zeichen, Zeichenketten und Texte 8.1 Die Eingabe einzelner Zeichen 8.2 Aufgaben 8.3 Eingabe und Bearbeitung von Zeichenketten 8.4 Die Ausgabe von Zeichenketten 8.5 Texte, Stringlisten und Dialoge 8.6 Aufgaben Literaturhinweise: • Küchlin/Weber: Einführung in die Informatik, Objektorientiert mit Java, Springer 1998 • Krüger, Guido: Handbuch der Java-Programmierung, http://www.javabuch.de oder Addison Wesley 2002 S. 1 Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 2 1. Anwendungen versus Applets Anwendungen sind Java-Programme, die durch den Java-Interpreter unter einem Betriebssystem ablaufen. Sie werden also nicht direkt ausgeführt, sondern „interpretiert“. Der Zweck der Übung ist es, Java-Programme maschinen- und betriebssystemunabhängig zu halten, also dafür zu sorgen, dass jedes Java-Programm auf jedem Rechner lauffähig ist, wenn nur ein JavaInterpreter existiert. Solche Programme laufen meist als Kommandozeilenversionen, weil es gar nicht so einfach ist, sie innerhalb eines Fensters der grafischen Oberfläche, also z. B. unter Windows oder KDE, laufen zu lassen. Der Einführungsunterricht mit Anwendungen unter Java arbeitet deshalb oft mit einer DOS-Box, ähnelt also sehr der Arbeitsweise vor 30 Jahren und verfügt so über weit weniger Komfort als etwa ein Uralt-Pascal-System. Applets haben dieses Problem nicht, weil sie innerhalb der HTML-Seite in einem Browser laufen, der fast immer ein eigenes Fenster hat. Einen Ausweg bieten integrierte grafische Entwicklungsumgebungen (IDEs) wie z. B. ©NetBeans von SUN, ©Eclipse (u.a. von IBM) oder der ©JBuilder von Borland. Diese leiten eine Anwendung von einer Form (einem Formular) ab, das schon über alle notwendigen Eigenschaften verfügt, um als eigenständiges Programm in einem Fenster zu laufen. Neue Anwendungen erben diese Eigenschaften. Die Programmierer ergänzen dann nur noch den Code, der spezifisch für das neue Programm ist. NetBeans und JBuilder benutzen zu diesem Zweck z. B. die Formulare des AWT (Abstract Windowing Toolkit) oder der Swing-Bibliothek. Damit bleiben die erstellten Programme maschinenunabhängig. Alle IDEs erfordern leider leistungsfähige Rechner, so dass die Arbeit auf älteren Schulrechnern etwas unerfreulich wird. Eine Abhilfe kann sein, einfach eine ältere Version der IDE zu benutzen. Als Konsequenz aus dieser Situation benutzen wir für die Arbeit mit Applets weitgehend selbst geschriebenen Code, der unter allen Browsern und Betriebssystemen lauffähig sein sollte. Die Schülerinnen und Schüler können so ihre Arbeitsergebnisse bei Bedarf im Internet veröffentlichen. Für Anwendungen aber nutzen wir die Vorlagen (Templates) der IDE. Die Unterschiede beim Programmieren sind minimal, weil der Code weitgehend von der IDE automatisch erzeugt (und bei NetBeans teilweise „versteckt“) wird. Die eigene Programmierarbeit verbleibt damit in jedem Fall im reinen Java. Auch die Arbeit mit den Systemen ähnelt sich so stark, dass ein Wechsel zu einem anderen System unproblematisch bleibt. Die Entwicklung von Anwendungen entspricht der Arbeit mit Delphi-, VisualBasic oder C++Systemen, die ohne den Umweg über Interpreter ausführbare Dateien erzeugen. JavaAnwendungen werden (meist) in JAR-Dateien „verpackt“ (auch dafür gibt es Werkzeuge in der IDE) und per Mausklick gestartet. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 3 2. Die Arbeit mit IDEs IDEs sind Werkzeuge zur Entwicklung von Programmen. Die Grundidee der Systeme besteht daraus, den Programmierern fertige Programmstrukturen und darin lauffähige Objektklassen für die Standardaufgaben eines Programms bereitzustellen. Die Programmierer erzeugen – auch hier von der IDE unterstützt – Exemplare1 (Instanzen, Objekte) der vorgegebenen Objektklassen, deren Datenfelder (Attribute) sie mit konkreten Werten füllen. Das geschieht weitgehend interaktiv am Bildschirm, indem die Exemplare entweder mit der Maus bearbeitet werden, um z. B. die Größe und Position zu bestimmen, oder durch das Setzen bestimmter Eigenschaften (Properties) wie Farbe oder Schriftart in einem Eigenschaften-Fenster des Objekt-Inspektors. Objekte agieren (meist) nicht selbst, sondern reagieren auf Ereignisse (Events), die z. B. durch einen Mausklick oder einen Tastendruck auf der Tastatur ausgelöst werden. Das Betriebssystem empfängt solche Ereignisse und reicht sie an die Elemente auf dem Bildschirm weiter. Ein typisches Mausereignis ist ein Doppelklick auf das Kreuz-Symbol in der oberen rechten Ecke eines Fensters, das z. B. eine Meldung „<Doppelklick an der Position (400,120)>“ erzeugt, die dann der Reihe nach an die Fenster des Desktops durchgereicht wird. Stellt das angeklickte Fenster fest, dass sein Kreuzchen getroffen wurde, dann reagiert es darauf, indem es sich selbst schließt. Die Objekte müssen somit • dem Systems bekannt gemacht werden, um die Botschaften des Systems zu empfangen, und • über Methoden verfügen, um auf die Standardereignisse des Systems zu regieren. Beides wird erreicht, indem alle Anwendungen von einer Mutterklasse Form abgeleitet werden, die über solche Eigenschaften verfügt und sie an die Tochterklassen vererbt. Die Reaktionen auf die Standardereignisse beruhen typischerweise darin, nichts zu tun. Weil die Elemente z. B. eines Windows-Programms ebenso wie die Standardereignisse festgelegt sind, kann das System fertige Programmschablonen erstellen, die die vom Programmierer am Entwicklungsbildschirm zusammengestellte Oberfläche aus Fenstern, Beschriftungen, Knöpfen, Ein- und Ausgabefeldern, ... erzeugen, ohne dass eine einzige Zeile Quelltext selbst geschrieben werden muss. Damit ist aber nur festgelegt, wie die Oberfläche aussieht, aber nicht, was sie tut. Bis auf wenige Standardreaktionen (z. B. Fenster verkleinern oder schließen) reagiert das Programm gar nicht! Das Programmieren unter IDEs besteht deshalb weitgehend daraus, die anfangs leeren Ereignisbehandlungsmethoden (Event-Handler) auszufüllen, indem Quelltext eingegeben wird, der beschreibt, wie das gerade bearbeitete Objekt auf einzelne Ereignisse zu reagieren hat: • Was passiert, wenn ein bestimmter Knopf angeklickt wird? (Das Programm wird beendet.) • Was passiert, wenn ein anderer Knopf angeklickt wird? (Eine Datei wird gespeichert.) • Was passiert, wenn eine Taste gedrückt wird? (Je nach gedrückter Taste wird anders reagiert.) • ... 1 Wir werden die Bezeichnungen wild gemischt benutzen, um einerseits halbwegs lesbares Deutsch zu schreiben und uns andererseits an den Computer-Slang zu gewöhnen. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 4 3. NetBeans-Anwendungen entwickeln Das Schreiben von Javaprogrammen geschieht im Allgemeinen in drei Phasen (genauer weiter hinten!): 1. Zusammenstellung der Programmoberfläche im Designer-Modus. Dazu werden Exemplare der Klassen erzeugt, die über dem Designerfenster am oberen Bildschirmrand angeboten werden, z. B. Fenster Knöpfe, Textfelder, ... Zuerst sollte dazu die gewünschte Bibliothek ausgewählt werden (bei uns etwas altmodisch: AWT). Die Eigenschaften dieser Exemplare werden mit Hilfe des Eigenschaftsfensters geeignet gesetzt. NetBeans erzeugt automatisch den dazu gehörende Java-Code. 2. Ausfüllen der benötigten Ereignisbehandlungsmethoden mit Quelltext. Nach Auswahl des gewünschten Ereignisses im Eigenschaftsfenster (z. B. des „mouseClicked-Ereignisses“) erzeugt NetBeans ggf. eine passende Adapterklasse sowie eine leere Java-Methode und springt an die richtige Stelle im Programm. Der „wohlüberlegte“ Text wird hier eingegeben. 3. Übersetzen und Testen des erzeugten Programms NetBeans übersetzt das Programm in ausführbaren Code und erzeugt eine ohne weitere Zusätze ausführbare Datei, die sofort gestartet wird. Das so erzeugte Programm wird normalerweise fehlerhaft sein, zumindest aber unvollständig. Deshalb sucht man die Fehler und ergänzt ggf. die Oberfläche bzw. ändert den Programmcode. Insgesamt wird mit einem grafischen Entwicklungssystem-System auf zwei verschiedenen Ebenen gearbeitet: • In der visuellen Entwicklungsumgebung werden Objekte erzeugt und mit Eigenschaften ausgestattet, die die spätere Programmoberfläche bilden. • Parallel dazu wird automatisch Programm-Quelltext erzeugt, der zur Laufzeit genau die in der Entwicklungsumgebung definierte Oberfläche nachbildet. Dieser wird ggf. per Hand verändert oder ergänzt. Visuelle Entwicklungsumgebung Java-Quelltext ...... Das ist ein Text in einem Fenster mit zwei Knöpfen ....... Ende ESC NetBeans vermittelt zwischen beiden Darstellungsarten. private void ende_click (Object source, Event evt) { } ... Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow 3.1 Erzeugen einer neuen leeren Anwendung Mit NetBeans erzeugen wir Anwendungen ähnlich wie Applets. Dazu starten wir NetBeans, wählen den Menüpunkt File Æ New Project…, benennen das Projekt und wählen das gewünschte Verzeichnis. Die beiden Häkchen bei „Set as Main Project“ und „Create Main Class“ lassen wir diesmal stehen. In diesem Projektverzeichnis erzeugen wir nun eine neue Anwendung über File Æ New… Wir wählen aus den GUI-Forms (das sind die, die über einen Designer verfügen) die AWT-FrameForm aus. Wir vergeben wie immer einen aussagekräftigen Namen für diese Anwendung und landen im Designer-Modus von NetBeans – genau wie beim Applet. Starten wir diese Anwendung durch Drücken von <Umschalt>-F6, dann ist das Ergebnis etwas mager: man findet nur den Minimalkopf einer Anwendung – die man aber immerhin auf die übliche Art wieder schließen kann. Geben wir im Designer bei den Properties eine Minimalgröße an – z. B. [300,200] bei minimumSize – und dann auch gleich einen schönen title als Fensterüberschrift, dann gefällt das Ergebnis schon viel besser. S. 5 Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 6 3.2 Der Quelltext Der Quelltext unserer JavaAnwendung enthält Java-Code und zusätzlich eine Reihe von Anmerkungen und Erklärungen. Da es sich um automatisch erzeugten Code handelt, in dem man nicht herumpfuDer automatisch schen sollte, wenn man nicht erzeugte Code sehr genau weiß, was man tut, wird versteckt. wird dieser Code weitgehend versteckt: die Methoden sind „eingeklappt“. Wenn wir alle Methoden aufklappen sehen wir eine Menge Kommentare (zwischen /* und */) sowie Quelltext. Nach dem Löschen der Kommentare verbleibt das folgende Programm, das wir uns nun wenigstens einmal etwas genauer ansehen wollen. package projektjavaanwendung1; public class Anwendung1 extends java.awt.Frame { 2. Im Konstruktor wird die Methode public Anwendung1() { initComponents aufgerufen. initComponents(); } private void initComponents() { setMinimumSize(new java.awt.Dimension(300, 200)); setTitle("Ein richtiges Fenster!"); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); 3. In initComponents werden die im Designer } eingestellten Eigenschaften per Code nach}); } pack(); vollzogen. Zusätzlich wird gesagt, was beim Schließen des Fensters zu tun ist. private void exitForm(java.awt.event.WindowEvent evt) { Beim Schießen wird dem Betriebssystem System.exit(0); } mitgeteilt, dass alles gut gegangen ist. } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { 1. Zuerst wird eine neue public void run() { Anwendung namens Annew Anwendung1().setVisible(true); wendung1 erzeugt und } sichtbar gemacht – durch }); Aufrufen des Konstruktors. } Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 7 Bei Programmläufen wird das Formular erzeugt und die Kontrolle an dieses übergeben. Im Normalfall wird danach auf Benutzeraktionen gewartet, die entsprechende Reaktionen auslösen. 3.3 Das Einfügen von Steuerelementen Wir wollen nur einen einzelnen Button einfügen, mit dessen Hilfe wir das Programm wieder beenden. Dazu setzen wir die Layout-Eigenschaft des Fensters auf null, wählen dann z. B. im AWT-Werkzeugfenster den Button aus und benennen ihn um in bEnde. Hier das Layout ändern! Variable im Kontextmenü umbenennen. Ändern wir seine Aufschrift (Eigenschaft label) in „Ende!“, verpassen ihm eine andere Schriftgröße (Eigenschaft font) und ändern seine Farbe (Eigenschaft background) in rot, dann sieht er schon recht gut aus. Auf Klick soll er das Programm (die „Anwendung“) beenden. Das erreichen wir – wie beim Applet – indem wir das Event action performed im Designer auswählen, dort doppelklicken und im Code der Ereignisbehandlungsmethode die schon bekannte Zeile System.exit(0); einfügen. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 8 Das Ergebnis ist beachtlich, wenn man bedenkt, dass wir nur 15 Zeichen Code geschrieben haben: private void bEndeActionPerformed (java.awt.event.ActionEvent evt) { System.exit(0); } 15 Zeichen Code! 3.4. Zeichnen Alle Komponenten (abgeleitet von Component) verfügen über eine Graphics-Komponente. Fenster-Formulare also auch. Diese müssen wir uns allerdings erstmal holen: Graphics g = getGraphics(); Wollen wir auf Knopfdruck eine Linie zeichnen, dann geht das so: private void bLinieActionPerformed(java.awt.event.ActionEvent evt) { Graphics g = getGraphics(); g.drawLine(100,100,200,200); } Weil NetBeans bei automatisch erzeugtem Code den vollen Pfad zu Objektbibliotheken und Methoden angibt (z. B. java.awt.event.ActionEvent evt), benötigt es keine importAnweisungen vor der Klasse. (Kann man vielleicht in anderen Versionen anders einstellen.) Die Namen werden dadurch allerdings in der Punkt-Schreibweise ziemlich lang. Es ist einfacher, bei Benutzung von Grafikmethoden ein import java.awt.*; vor der Klassendeklaration einzufügen. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 9 4. Zeichenketten 4.1 Bezug zum Unterricht Die im Unterricht benutzten Elemente einer Programmiersprache sollten sich nicht aus Vollständigkeits- oder anderen fachimmanenten Überlegungen ergeben, sondern möglichst aus einer Problemstellung abgeleitet werden, die Bezug zu den Möglichkeiten und Folgen der Anwendung von Informatiksystemen hat. Da außer bei grafischen Problemen fast die gesamten Ein- und Ausgabe von Programmen über Zeichenketten erfolgt, ergeben sich entsprechend viele Anwendungsmöglichkeiten: • Reine Datenverarbeitung (Daten einlesen, Typkonvertierungen, verarbeiten, ausgeben) • Verschlüsselung (Sicherheit, eCommerce, Vertrauen im Netz, ...) • Symbolverarbeitung (Computeralgebra, DNA-Strukturen, mathematische Anwendungen...) • Textinterpretation (Syntax, Mustererkennung, Übersetzung, Ersetzung, Suchvorgänge, ...) Nebenbei bietet die Zeichenkettenverarbeitung gute Möglichkeiten zur Binnendifferenzierung und eine Fülle von Aufgaben zur Leistungsmessung, die von sehr einfachen Fällen für den Anfangsunterricht bis zu ziemlich kniffeligen Problemen reichen. 4.2 Oberfläche und Ereignisverarbeitung Zeichenketten werden innerhalb des Java-Programms verarbeitet. Um Ausgangsmaterialien einzulesen und Ergebnisse darzustellen, benötigt man eine Verknüpfung mit Darstellungskomponenten des Bildschirms, die ziemlich beliebig ist. Wir wollen uns hier zur Darstellung auf Textfelder in einer Anwendung beschränken und Aktionen mit Knöpfen auslösen. import java.awt.*; public class Anwendung1 extends java.awt.Frame { public Anwendung1() { initComponents(); } … Oberfläche mit Textfeldern und Buttons Javaprogramm, das die gewünschten Aktionen ausführt Die Arbeitsweise solcher Programme ist – wie schon gesagt - immer gleich: • zuerst wird die grafische Oberfläche (GUI) erzeugt und angezeigt, • dann wartet die Anwendung auf Eingaben, z. B. auf aus Eintippen eines Textes in ein Textfeld, (schon dabei werden jede Menge Ereignisse (Events) ausgelöst, z. B. beim Loslassen einer Taste, die wir hier aber ignorieren wollen), • beim Anklicken eines Knopfes (Buttons) wird ein Ereignis ausgelöst, das im Programm den gewünschten Ablauf startet. Dazu holt sich das Programm die erforderlichen Daten aus den GUI-Komponenten, verarbeitet sie und stellt die Ergebnisse auf diesen oder anderen GUI-Komponenten dar. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 10 4.3 Die Erzeugung von GUI-Komponenten Wir benötigen von den GUI-Komponenten des AWT (abstract windowing toolkit) von Java nur Label-, TextField- und Button-Objekte. Wir erzeugen sie mit Hilfe des NetBeansDesigners, der auf der Registerkarte gleich neben dem Editor zu finden ist. Umschalten zwischen Editor und Designer einige Eigenschaften (Layout, Name wechseln, …) werden im Kontextmenü gesetzt Das Formular Eigenschaften AWTKomponenten Im Kontextmenü des Formulars setzen wir das Layout auf null (damit werden die Komponenten frei positionierbar), wählen dann aus der AWT-Palette die Label-Komponente („A“) aus und platzieren ein solches Objekt auf das Formular (durch Klicken). Danach ändern wir die Eigenschaften des Label-Objekts: Wir setzen die Schriftgröße (font) z. B. auf 40, wählen als Text das Wort „Hallo!“ in rot und zentriert und können auch noch den Namen von label1 z. B. auf lBegruessungstextanzeige ändern. Der von NetBeans erzeugte Quelltext lautet: package projektanwendungmitzeichenketten; public class AnwendungMitZeichenketten extends java.awt.Frame { public AnwendungMitZeichenketten() { initComponents(); wie immer: die Komponenten } werden in initComponents mit Eigenschaften versehen Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 11 private void initComponents() Label-Komponente { erzeugen. setLayout(null); lBegruessungstextanzeige = new java.awt.Label(); lBegruessungstextanzeige.setAlignment(java.awt.Label.CENTER); lBegruessungstextanzeige.setFont(new java.awt.Font ("Cooper Black", 0, 40)); lBegruessungstextanzeige.setForeground(java.awt.Color.red); lBegruessungstextanzeige.setText("Hallo!"); lBegruessungstextanzeige.setBounds(120, 170, 290, 130); add(lBegruessungstextanzeige); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); Eigenschaften der Label-Komponente setzen. } }); pack(); } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); wie immer } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new AnwendungMitZeichenketten().setVisible(true); } }); Label-Komponente } global vereinbaren } // Variables declaration - do not modify private java.awt.Label lBegruessungstextanzeige; // End of variables declaration Die nicht fett gesetzten Quelltextzeilen sind „Bürokratie“ und können von uns ignoriert – aber nicht gelöscht! - werden. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 12 4.4 Die Verarbeitung von Ereignissen Wollen wir später auf die per Designer erzeugten GUI-Elemente zurückgreifen (was meist der Fall ist), dann sollten wir bei den Optionen von NetBeans darauf achten, dass die Komponenten als globale Variable erzeugt werden. Wir wollen uns hier auf Reaktionen beschränken, so einstellen! die auf das Anklicken eines Buttons erfolgen. Dazu müssen wir den Button – als Ereignissender - mit einem Ereignisempfänger verbinden (einem Listener), der die gewünschten Aktionen mit einer Ereignisbehandlungsmethode auslöst. Wir wollen beim Button das ActionEvent benutzen, das durch das Anklicken ausgelöst wird. (Genauso gut hätten wir auch ein Mausereignis nehmen können!) Es gibt in Java sehr viele verschiedene Möglichkeiten, auf Ereignisse zu reagieren. Wir wollen hier das von NetBeans automatisch erzeugte Verfahren besprechen: Die in Java benutzten Listener reagieren meist auf eine ganze Reihe von Ereignissen, für die wir dann die entsprechenden Methoden schreiben müssen – auch dann, wenn wir sie gar nicht benötigen. Um das zu umgehen, gibt es die so genannten Adapterklassen, die für alle benötigten Methoden leere Methodenrümpfe besitzen. Aus solch einer Adapterklasse leitet NetBeans dann eine Tochterklasse ab, die die nicht benötigten leeren Methoden erbt und nur die im Eigenschaftsfenster angegebenen Methoden überschreibt. Das ist auf den ersten Blick umständlich, spart aber Schreibarbeit. Doppelklicken wir im Designer auf den Button button1, dann wird eine anonyme Klasse (ohne Namen) erzeugt und dem Button als ActionListener zugeordnet. button1.addActionListener(new java.awt.event.ActionListener() … Diese Klasse enthält eine Methode actionPerformed, die beim Anklicken des Buttons aufgerufen wird und die diesen Aufruf an eine weitere Methode button1ActionPerformed weiterreicht. button1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { button1ActionPerformed(evt); hier wird die actionPerformed} Methode aufgerufen, in der wir }); den eigentlichen Code platzieren Die Abläufe sind dann so: Vorbereitung: ActionListenerKlasse angeben … … und beim Button als Listener anmelden … Ausführung: Der Button wird angeklickt ein ActionEvent wird dem Listener übergeben … und auf Action-Ereignisse warten die actionPerformedMethode des Applets wird vom Listener aufgerufen und löst die gewünschten Aktionen aus Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 13 Ein Beispiel, bei dem sich auf Mausklick die Aufschrift des Buttons ändert, sieht so aus: package projektanwendungmitzeichenketten; public class AnwendungMitZeichenketten extends java.awt.Frame { public AnwendungMitZeichenketten() { initComponents(); } button1 erzeugen und dessen Eigenschaften private void initComponents() einstellen { button1 = new java.awt.Button(); setLayout(null); setMinimumSize(new java.awt.Dimension(300, 200)); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); button1.setBackground(java.awt.Color.yellow); button1.setFont(new java.awt.Font("Dialog", 1, 24)); button1.setForeground(java.awt.Color.red); button1.setLabel("Hallo!"); button1.setBounds(80, 70, 190, 140); button1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { button1ActionPerformed(evt); } ActionListener (s.o.) hinzufügen }); } add(button1); pack(); private void button1ActionPerformed(java.awt.event.ActionEvent evt) { button1.setLabel("hat geklappt!"); Reaktion auf Mausklicks } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new AnwendungMitZeichenketten().setVisible(true); } }); } private java.awt.Button button1; } Button global vereinbaren Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 14 Das Ergebnis (nach Mausklick) : 4.5 Eine Anwendung zur Ein- und Ausgabe von Zeichenketten Wir wollen zwei Textfelder benutzen, deren Inhalte wird mit den Methoden getText() bzw. setText() lesen und beschreiben können. Ein Start-Button soll die Verarbeitung einleiten. Zwei Label-Komponenten beschriften die Felder. Der Inhalt des oberen Eingabefeldes soll in Grossbuchstaben im unteren dargestellt werden. Wir erzeugen die benötigten Komponenten (zwei Label, zwei Textfelder und einen Button) im Designer und stellen die Eigenschaften so ein, dass das Ergebnis dem folgenden Screenshot ähnelt. Dabei vergessen wir nicht, die Abmessungen (Projekteigenschaften …) so einzustellen, dass auch alles zu sehen ist und die Komponenten sinnvoll zu benennen. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 15 Nun müssen wir nur noch auf die ActionPerformeld-Methode des Buttons klicken (bei den Events) und drei (hier fett und rot gedruckte) Zeilen im Editor in die ActionPerformedMethode schreiben: package projektanwendungmitzeichenketten; public class AnwendungMitZeichenketten extends java.awt.Frame { public AnwendungMitZeichenketten() // … (wie immer) private void { tfEingabe label1 label2 tfAusgabe bStart initComponents() = = = = = new new new new new java.awt.TextField(); java.awt.Label(); java.awt.Label(); java.awt.TextField(); java.awt.Button(); Komponenten erzeugen setLayout(null); setMinimumSize(new java.awt.Dimension(400, 150)); addWindowListener(new java.awt.event.WindowAdapter() // … (wie immer) label1.setFont(new java.awt.Font("Dialog", 1, 14)); label1.setText("Eingabe:"); label1.setBounds(10, 40, 70, 23); add(label1); Eigenschaften setzen label2.setFont(new java.awt.Font("Dialog", 1, 14)); label2.setText("Ausgabe:"); label2.setBounds(10, 70, 80, 23); add(label2); tfEingabe.setBounds(90, 40, 310, 20); add(tfEingabe); tfAusgabe.setBounds(90, 70, 310, 20); add(tfAusgabe); bStart.setBackground(java.awt.Color.orange); bStart.setLabel("Start"); bStart.addActionListener(new java.awt.event.ActionListener() // … (wie immer) bStart.setBounds(160, 100, 41, 24); add(bStart); pack(); private void bStartActionPerformed(java.awt.event.ActionEvent evt) { String eingabe = tfEingabe.getText(); Text holen, umString ausgabe = eingabe.toUpperCase(); wandeln und austfAusgabe.setText(ausgabe); geben } private void exitForm(java.awt.event.WindowEvent evt) // … (wie immer) public static void main(String args[])// … (wie immer) private private private private private } java.awt.Button bStart; java.awt.Label label1; java.awt.Label label2; java.awt.TextField tfAusgabe; java.awt.TextField tfEingabe; Komponenten global vereinbaren Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow Das Ergebnis: S. 16 Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten S. 17 Eckart Modrow 5. Methoden zur Zeichenkettenverarbeitung Zeichenketten bezeichnet man als Strings. Es gibt eine String-Klasse und eine StringBufferKlasse. Sie unterscheiden sich dadurch, dass Strings als final deklariert, StringBuffer aber dynamisch sind. Verändert man also Strings, so erhält man einen neuen String, während StringBuffer geändert werden. (Es gibt auch noch andere Unterschiede.) Für unsere Zwecke sind die Unterschiede ohne Bedeutung: wir verwenden Strings. Einen Strings können wir uns als eine Folge von Zeichen vorstellen, wobei die Nummerierung bei Null beginnt. Die Zählung beginnt bei 0! D a s i s t e i n S t r i n g Im String stehen 16-Bit-Unicode-Zeichen. Bei Bedarf können wird diese Zeichen durch Typecasting in ganze Zahlen umwandeln - z. B. um die Ordnungsnummer des Zeichens zu bestimmen: int i = (int)’c’; Will man solche Zahlen in Textfeldern darstellen, dann gibt es drei „Tricks“ dafür: • Entweder man verwandelt die ganze Zahl in ein Objekt der Wrapper-Klasse Integer, das dann in einen String umgewandelt wird: raus.setText(new Integer(i).toString()); • oder man hängt die Zahl einfach an einen existierenden String (z. B. ein Leerzeichen) an – dann erfolgt eine automatische Typumwandlung. Zur Not kann man das erste Zeichen dann wieder entfernen: raus.setText(“ “+i); • oder man benutzt eine der statischen Umwandlungsmethoden valueOf() der String-Klasse: raus.setText(String.valueOf(i)); Von den zahlreichen Methoden der String-Klasse wollen wir nur einige benutzen: charAt(int) liefert das entsprechende Zeichen zurück compareTo(String) vergleicht mit einem String concat(String) verbindet mit einem String indexOf(String) liefert den Index des ersten Zeichens des Teilstrings length() liefert die Länge des Strings replace(char1, char2) ersetzt alle Zeichen char1 durch char2 substring(int, int) liefert einen Teilstring toLowerCase() konvertiert in Kleinschreibung toUpperCase() konvertiert in Grossschreibung toString() wandelt ein Objekt in einen String um Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow 6. S. 18 Verschlüsselungsverfahren Eines der ältesten kryptografischen Verfahren ist das Cäsar-Verfahren, bei dem alle Zeichen zyklisch um eine Stelle im Alphabet verschoben werden: AÆB, BÆC, ..., ZÆA In der folgenden Verschlüsselungsmethode wird ausgiebig vom Typecasting Gebrauch gemacht: Zeichen werden in Zahlen und diese wieder in Zeichen umgewandelt. private void bStartActionPerformed(java.awt.event.ActionEvent evt) { String eingabe = tfEingabe.getText().toUpperCase(); String ausgabe = ""; int max = (int)'Z'; int min = (int)'A'; for(int i=0;i<eingabe.length();i++) { char c = eingabe.charAt(i); int nr = (int)c; nr = nr + 1; if (nr > max) nr = (nr-max)+min-1; ausgabe = ausgabe+(char)nr; } tfAusgabe.setText(ausgabe); } Die Zeichen können natürlich auch um andere Werte verschoben werden. Versetzungsverfahren: Die Zeichen werden zeilenweise in einen „Block“ der Breite n geschrieben und spaltenweise wieder ausgelesen: Klartext: DIE GROESSTEN KRITIKER DER ELCHE WAREN FRUEHER SELBER WELCHE Block mit n=8: D S I E W U L C I S T R A E B H E G T E N I K E E L R E N H E R E R E R O K R C H F S W E E R D E R E L Geheimtext: DSIEWULCISTRAEBHETI RHEE EKEEER GNELNR R RC W OK HFSE ERDEREL Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 19 XOR-Verschlüsselung: Der Klartext wird mit Hilfe eines Schlüsselwortes verschlüsselt. Dazu werden Klartext und der ggf. wiederholte Schlüssel untereinander geschrieben. Die Ordnungsnummern der Zeichen werden in die Dualdarstellung gebracht und bitweise xor-verschlüsselt: Stehen zwei gleiche Ziffern (Nullen oder Einsen) übereinander, dann ergibt sich eine Null, sonst eine Eins. Das Verfahren ist durch nochmalige Verschlüsselung umkehrbar und schnell. Die Schlüssel können z. B. in einer Chipkarte gespeichert sein. Klartext: Schlüssel: GEHEIM TEST 71 69 72 69 73 77 84 69 83 84 84 69 1000111 1000101 1001000 1000101 1001001 1001101 1010100 1000101 1010011 1010100 1010100 1000101 0010011 0000000 0011011 0010001 0011101 0001000 19 0 27 17 29 8 Das Ergebnis wird wieder in eine Zeichenfolge umgewandelt (die hier aber nicht im normalen Zeichensatz liegt). Blockweises Chiffrieren: Die Zeichen werden „fest verdrahtet“ auf einander abgebildet. Die „Verdrahtung“ ist gut auf einer Chipkarte unterzubringen. A B C D E F G H I J K ….. A B C D E F G H I J K ….. Einwegverfahren: Die Verfahren beruhen darauf, dass Zahlen, insbesondere große, leicht multipliziert, aber nur schwer faktorisiert werden können. Damit wird es möglich, einen öffentlichen Schlüssel (public key) frei zu verteilen, mit dem Texte verschlüsselt werden. Nur mit einem dazu passenden privaten Schlüssel (private key) können sie wieder entschlüsselt werden. Das bekannte RSA-Verfahren, mit dem z. B. die Pretty-Good-Privacy-(PGP)-Verfahren des Internets arbeiten, funktioniert wie folgt: Hat man zwei Primzahlen p und q sowie zwei Zahlen n=p*q und r<n, dann gilt: Z(p-1)*(q-1)*r+1 modulo (p*q) = Z Wählt man jetzt zwei natürliche Zahlen x und y, für die gilt: x*y = (p-1)*(q-1)*r+1 dann können wir mit ihrer Hilfe eine Zahl Z verschlüsseln und wieder entschlüsseln: Zx*y modulo n = (Zx)y modulo n = Z Wir geben deshalb den öffentlichen Schlüssel x und die Zahl n allgemein bekannt, und dazu das Kodierungsverfahren: Mit allen Zeichen des Klartextes tue Z Ordnungsnummer des Zeichens V Z x modulo n Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten S. 20 Eckart Modrow Die Dekodierung erfolgt mit Hilfe des privaten Schlüssels y: Mit allen Zeichen des verschlüsselten Textes tue V Ordnungsnummer des Zeichens Z V y modulo n Wir wollen das Verfahren an einem Beispiel durchgehen: Als Primzahlen wählen wir: deren Produkt ist Als r wählen wir beliebig und damit das Produkt x bestimmen wir so, dass auch y eine ganze Zahl ist und erhalten für y p = 97 und q = 151, n = 14647. r = 11, x*y = 96*150*11+1 = 144001. x = 19 y = 7579. Jetzt kann es losgehen: Wir verschlüsseln das Klartextzeichen „A“: Ordnungsnummer Z von „A“: Z = 65 verschlüsselte Zeichennummer V: V = 6519 modulo 14647 = 12561 Der Empfänger möchte wieder entschlüsseln: Geheimzeichennummer V: V = 12561 Klartextzeichennummer Z: Z = 125617579 modulo 14647 = 65 Klartextzeichen: „A“ Da sich bei dem Verfahren riesige Zahlen durch die Potenzen ergeben, benötigen wir noch ein schnelles Verfahren, um die Reste dieser Potenzen zu berechnen: Berechnung von r = BasisExponent modulo n: b Basis e Exponent r 1 SOLANGE e <> 0 TUE e ist eine gerade Zahl Wahr Falsch b (b*b) MOD n e e DIV 2 e r e- (r * b) MOD Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow 7. S. 21 Aufgaben: 1. a: Realisieren Sie das Cäsar-Verfahren für beliebige Verschiebungswerte. Entwickeln Sie eine GUI, in der die Verschiebungsweite ausgewählt werden kann. Entschlüsseln Sie die Texte auch wieder. b: Realisieren Sie das Versetzungsverfahren. Ermöglichen Sie auch hier Wahlmöglichkeiten. c: Realisieren Sie die XOR-Verschlüsselung. Wandeln Sie dazu die Zeichen in Bitfolgen um. Probieren Sie alternativ den XOR-Operator für Zahlen aus. 2. a: Realisieren Sie das beschriebene Verfahren zur Berechnung von Resten großer Potenzen. b: Benutzen Sie alternativ für diese Berechnung die Java-Klasse BigInteger. 3. Verschlüsseln Sie längere Texte und stellen Sie die Verteilung der Zeichen in Tabellenform oder grafisch als Histogramm dar. Versuchen Sie die Zeichen anhand der Zeichenhäufigkeit zu entschlüsseln. Funktioniert das bei allen Verfahren? 4. a: Extrahieren Sie eine Zahl, die als Zeichenkette eingegeben wurde. Benutzen Sie das Java-Hilfesystem. b: Geben Sie Rechenaufgaben als Zeichenketten ein: „3+4=“, „12-5=“, ... Suchen Sie die Zahlen und die Operatoren im String und geben Sie das Ergebnis aus. c: Analysieren Sie Polynome, die als String eingegeben werden. Beginnen Sie mit einstelligen ganzen Zahlen als Koeffizienten und Exponenten. „f(x)=3*x^2-2*x-1“. Weiten Sie dann die Zahlendarstellung aus. d: Stellen Sie die Graphen der eingegebenen Funktionen dar. 5. a: Benutzen Sie die Lösung aus 4.b, um die Ableitung ganzrationaler Funktionen zu bestimmen. b: Diskutieren Sie das Problem, Produkt-, Quotienten- und Kettenregel auf entsprechende Funktionen anzuwenden. Welche Teilprobleme müssen gelöst werden? Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 22 8. Zeichen, Zeichenketten und Texte Neben der Computergrafik ist der Umgang mit Texten die Hauptaufgabe von Computerprogrammen. Texte treten dabei in unterschiedlicher Form auf: • Es kann sich um einzelne Zeichen handeln, die bestimmte Aktionen auslösen sollen oder z. B. zu Zahlen zusammengesetzt werden. • Aufeinanderfolgende zusammengehörende Zeichen bilden Zeichenketten, sogenannte Strings, die z. B. Erläuterungen zum Zustand des Programms oder Daten (Nachname, Vorname, ...) enthalten. • Mehrere Zeichenketten bilden Texte im üblichen umgangssprachlichen Sinn, die bearbeitet, gespeichert und wieder geladen werden. Die Bedeutung solcher Zeichenkombinationen (von Literalen) ist erst einmal offen. Spezielle Zeichenfolgen bilden Zahlen, andere Postleitzahlen usw. Diese Interpretation der Zeichenketten muss besonderen Programmteilen überlassen werden, die meist entsprechende Typumwandlungen bewirken. 8.1 Die Eingabe einzelner Zeichen Wenn eine Taste der Tastatur gedrückt wird, dann ist noch nicht klar, welches der laufenden Programme das Ergebnis dieses Tastendrucks auswerten soll. Allerdings hat immer nur ein Element des Windows-Bildschirms den Fokus, ist also ausgewählt. (Meist wird ein Element durch einen Mausklick oder durch das Drücken der Tabulatortaste vom Benutzer ausgewählt; manchmal steuert aber auch ein Programm den Fokus.) Dieses Element kann dann auf Ereignisse reagieren, die von der Tastatur ausgelöst werden. Standardereignisse sind: • keyPressed und keyReleased mit denen der Zustand von Tastatur und Maus beim Drücken bzw. Loslassen einer Taste abgefragt werden kann. Auch Sondertasten und Tastenkombinationen werden angezeigt. • keyPressed, mit dessen Hilfe das eingegebene Zeichen ermittelbar ist. Zeichen werden wie alle anderen Größen als Bitfolgen gespeichert. In Java werden zwei Byte (also 16 Bit) zur Zeichendarstellung verwandt. Da darin 216 = 65536 verschiedene Zustände möglich sind, können auch 65536 verschiedene Unicode-Zeichen benutzt werden – es sind also so ziemlich alle Zeichensätze und Sprachen darstellbar. In anderen Systemen wird oft nur eine 8-Bit-Zeichendarstellung benutzt, weil ältere Rechner dieses Format benutzen. Das achte Bit wird manchmal auch zur Kontrolle der Richtigkeit der Übermittlung benutzt. In beiden Fällen sind nur 128 unterschiedliche Zeichen möglich, und damit führen nationale Sonderzeichen wie die deutschen Umlaute zu Fehlern. In Java schließt man Zeichen in Hochkommas ein (z. B. als ´a´). Davon gibt es verschiedene. Nehmen Sie das über dem # auf der Tastatur. Welches Zeichen nun welcher Bitfolge entspricht, wird durch den benutzen Zeichencode festgelegt. Oft wird der American Standard Code for Information Interchange benutzt, den man als ASCII abkürzt. Die ersten 128 Zeichen dieses Codes enthalten große und kleine Buchstaben, Ziffern, Satzzeichen des amerikanischen Alphabets sowie einige Sonderzeichen für die Wagenrücklauf-(Return)-Taste (Zeichen 13), die ESC-Taste (Zeichen 27) und andere. Die Bezeichnung der Sonderzeichen stammt teilweise noch aus den Fernschreiber-Zeiten, in denen z. B. das Zeichen Bell (Zeichen 8) die Fernschreibklingel läuten ließ. (Heute bewirkt es meist einen Piepton.) Windows benutzt einen ISO-Code (von International Organization for Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 23 Standardization), der bei Zeichen mit Ordnungsnummern ab 128 vom ASCII abweicht und z. B. nationale Sonderzeichen enthält. Die ASCII-Tabelle, in der die Zuordnung von Zeichen zu ihren Ordnungsnummern aufgeführt ist, findet man in fast allen Programmierhandbüchern. Viel einfacher ist es aber, sich die Nummern der gerade benötigten Zeichen von einem Programm ausgeben zu lassen. Man drückt die gewünschte Taste und liest die Ordnungsnummer ab. Der 16-Bit-Datentyp Zeichen wird in Java als char bezeichnet. Die Ordnungsnummer eines Zeichens ermittelt man über eine Typumwandlung (type-casting): Hat man ein Zeichen c, dann liefert (int) c seine Ordnungsnummer. (Dabei können sehr große Ordnungsnummern auch negative Zahlen liefern.) (Umgekehrt liefert der Aufruf (char) i das Zeichen mit der Ordnungsnummer i.) Wollen wir die ermittelte Nummer (eine ganze Zahl) wieder am Bildschirm darstellen, dann müssen wir sie z. B. mit der Methode valueOf der String-Klasse in eine Zeichenkette verwandeln: label1.setText(String.valueOf(i)); Wir wollen die Zeicheneingabe vom Formular selbst auswerten lassen. Dazu fügen wir neun Label-Komponenten ein, von denen fünf einen erläuternden Text enthalten (Setzen Sie entsprechend die Eigenschaft text der Komponenten.), die sechste das Zeichen selbst, die siebente die Ordnungsnummer des Zeichens und die anderen angeben, welche Sondertasten gedrückt wurden. Die Ordnungsnummer soll ermittelt werden, wenn eine Taste losgelassen wird. Wir wählen deshalb das keyReleased-Ereignis des Formulars. Zur Abfrage der gedrückten Taste benutzen wir die Konstanten des KeyEvents, z. B. evt.VK_SHIFT. private void formKeyReleased(java.awt.event.KeyEvent evt) { label6.setText(String.valueOf(evt.getKeyCode())); if (evt.getKeyCode() == evt.VK_SHIFT) label7.setText("ja"); else label7.setText("nein"); if (evt.getKeyCode() == evt.VK_CONTROL) label8.setText("ja"); else label8.setText("nein"); if (evt.getKeyCode() == evt.VK_ALT) label9.setText("ja"); else label9.setText("nein"); } Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 24 Wir ermitteln damit einige Ordnungsnummern und den Zustand der Shift-Taste: Zeichen Code Shift Zeichen Code Shift ´´ 32 false ´0´ 48 ´A´ 65 true ´?´ ´.´ 190 false ´a´ 65 false false Zeichen Code Shift return 13 false 219 true esc 27 false F1 48 112 Æ 39 false Å 37 false ↑ 38 false 8.2 Aufgaben 1. Erzeugen Sie ein Formular und darauf eine Label-Komponente namens Ausgabe. Ergänzen Sie das Programm so, dass a: nur große Buchstaben erscheinen. b: nur Buchstaben, aber keine anderen Zeichen eingegeben werden können. c: bei Eingabe eines beliebigen Zeichens ein Stern „*“ im Eingabefeld erscheint. d: die eingegebenen Zeichen „rückwärts“ dargestellt werden, also das zuletzt eingegebene Zeichen ganz links. 2. Zahlen kann man aus einzelnen Zeichen zusammensetzen: Immer wenn eine neue Ziffer eingegeben wird, verschiebt man die alten um eine Stelle „nach links“ (multipliziert sie also mit 10) und hängt die neue Ziffer „rechts“ an. Den Wert einer Ziffer erhält man durch einen einfachen Trick: Da die Ziffern „0“ bis „9“ im ASCII aufeinander folgen, zieht man die Ordnungsnummer der eingegebenen Ziffer von der Ordnungsnummer der „0“ ab. Wird ein Zeichen eingegeben, das keine Ziffer ist, dann ist die Zahleneingabe beendet. Zahl 0 Lies ein Zeichen von der Tastatur SOLANGE das letzte Zeichen eine Ziffer war TUE Zahl 10*Zahl + ORD(Zeichen) – Ord(´0´) Lies ein Zeichen von der Tastatur a: Realisieren Sie das Verfahren. b: Führen Sie eine Korrekturmöglichkeit ein: Die Ziffer! -Taste löscht die letzte eingegebene c: Ermöglichen Sie die Eingabe von ganzen Zahlen mit Vorzeichen. d: Ermöglichen Sie die Eingabe von Gleitpunktzahlen, den Zahlen mit einem Nachkommateil. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow 3. S. 25 In vielen Fällen kann man Fehler schon bei der Eingabe vermeiden, indem nur zulässige Werte vom Programm angenommen werden. Führen Sie Editierfelder ein, die a: nur Datumswerte der Form tt.mm.jj annehmen. b: Dezimalzahlen automatisch in Prozentwerte umformen und anzeigen. c: nur Schiffspositionen in der Form nnn°mm´ss´´ (Grad-Bogenminuten-Bogensekunden) annehmen. 8.3 Die Eingabe und Bearbeitung von Zeichenketten Im Gegensatz zu einzelnen Zeichen will man bei der Eingabe von ganzen Zeichenketten nicht auf Korrekturmöglichkeiten verzichten. Erst nach der Eingabe eines dafür vorgesehenen Zeichens – der RETURN-Taste (Zeichen 13) – soll die Eingabe an das System „abgeschickt“ werden. Einige Sonderzeichen wie Å (Zeichen 8) und <Entf> (Zeichen 46) dienen zur Korrektur der vorherigen Eingabe. In der Zwischenzeit muss die „Eingabezeile“ aber irgendwo bleiben. Zeichenketten werden in Java in Variablen des Typs String gespeichert. Stringliterale werden durch Anführungszeichen eingeschlossen (nicht durch Hochkommas). Die aktuelle Länge des Strings wird von der Methode length()ermittelt. (Sie kann einige Tausend Zeichen betragen, obwohl das nicht sehr sinnvoll ist.) Das i-te Zeichen innerhalb des Strings kann mit der Methode charAt(..) erhalten werden. (Die Zählung beginnt bei 0.) Hat also eine String-Variable nachname den Wert Meier, dann erhält man das „i“ durch nachname.charAt(2);. Man kann auch Zeichen ändern: Der Befehl s = nachname.replace(’i’,’y’) macht aus Herrn Meier einen Herrn Meyer. Eine einfache Möglichkeit zur Zeichenketteneingabe ist es also, den benötigten String einfach aus den eingegebenen Zeichen „zusammenzubasteln“. Wir wollen uns den Wert einer Variablen „Nachname“ zusammensuchen: Nachname ““ Lies ein Zeichen von der Tastatur SOLANGE das letzte Zeichen nicht die RETURN-Taste war TUE Nachname Nachname + Zeichen Lies ein Zeichen von der Tastatur Hat man solch einen String erst einmal im Speicher, dann kann eine ganze Reihe von Stringbearbeitungsfunktionen auf ihn angewandt werden: • Die Methode indexOf (char) liefert den Index des ersten Auftretens des Zeichens im String. Wird der Teilstring nicht gefunden, erhält man den Wert -1. Beispiel: s = “Meier“; s.indexOf(’i’); liefert 2. • Die Methode substring(int,int liefert einen String mit den Zeichen zwischen den angegebenen Positionen. Zu beachten ist, dass die zweite Zahl den Index nach dem letzten gewünschten Zeichen angibt. Beispiel: s = “Meiers“; s.substring(1,5); liefert “eier“. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow • S. 26 Weil Strings in Java als Referenztypen implementiert werden, enthält eine Stringvariable nicht den Wert des Strings, sondern seine Adresse. Vergleicht man also z. B. zwei Strings, dann werden ihre Adressen verglichen, nicht ihre Inhalte! Zeichenketten vergleicht man mit der Methode equals(..). Beispiel: s = “Meier“; s.equals(“Meyer“) liefert false. Etwas komfortabler gestaltet sich die Eingabe von Strings, wenn wir Editierfelder benutzen. Falls deren Eigenschaft editable den Wert true hat (Voreinstellung), können wir die dargestellte Textzeile bearbeiten, also auch während des Programmlaufs eingeben und im Programm auswerten. Der eingegebene Text findet sich in der text-Eigenschaft des Feldes. Entwerfen wir ein Formular mit zwei Editierfeldern und einem Button, so können wir in dessen Ereignisbehandlungsmethode „irgendetwas“ (Beispiel vorher: Verwandlung in Großschrift) damit machen. 8.4 Die Ausgabe von Zeichenketten Zeichenketten könne praktisch überall dort ausgegeben werden, wo eine „Beschriftung“ möglich oder erforderlich ist, also • als text-Eigenschaft von Komponenten, vor allem der label-Komponenten, die gerade zur Anzeige von Zeichenketten gedacht ist. Haben wir eine Label-Komponente namens Anzeige auf einem Formular form1 und einen auszugebenden Text in einer Variablen s, dann zeigt der Befehl form1.Anzeige.text.setText(s); diesen Text an. • als Ergebnis der drawString-Methode eines Grafik-Kontextes. Diese „zeichnet“ den Text ab der angegebenen Position. Wollen wir z. B. auf der Graphics-Komponenten g eines Formulars form1 schreiben, dann funktioniert g.drawString("Hallo",150,60); (Achtung: nicht import java.awt.*; vor der Klasse vergessen! private void button1ActionPerformed(java.awt.event.ActionEvent evt) { Graphics g = getGraphics(); g.drawString("Hallo",150,60); } } • als Inhalt der text-Eigenschaft eines Editierfeldes, dessen editable-Eigenschaft bei Bedarf auf TRUE gesetzt wird (s.o.). Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 27 Unabhängig von den Komponenten eines Formulars können Texte auch in eigenen Meldungsfenstern angezeigt werden • Am einfachsten geschieht das mit der Methode JOptionPane.showMessageDialog aus der Klasse javax.swing, die eine Textzeile in der Mitte des Bildschirms anzeigt. Wir wollen so eine Meldung beim Mausklick auf einen Knopf namens button1 erscheinen lassen: private void button1ActionPerformed(java.awt.event.ActionEvent evt) { javax.swing.JOptionPane.showMessageDialog (null,"Hallo, das ist eine Meldung!"); } 8.5. Ein einfacher Editor Will man mehr als eine Textzeile anzeigen oder bearbeiten, dann benötigt man Komponenten, die entsprechenden Speicherplatz sowie die Methoden zum Umgang mit diesen Texten bereitstellen. Einige Objekte, z. B. die TextArea-Komponente, verfügen über eine solche Eigenschaft. Sie verwalten einen langen String, in dem sich Zeilenvorschubszeichen („\n“ von „new line“) befinden können. Die Zeichen zwischen diesen Trennzeichen werden als Zeilen des Textes interpretiert. Wählen wir die etwas komfortablere jTextArea-Komponente aus der Swing-Palette, dann kann diese ihren Inhalt sogar in einer Datei speichern bzw. von dort laden. Als Beispiel wollen wir diese jTextArea -Komponente etwas genauer ansehen. Sie enthält einerseits eine Zeichenkette namens text, andererseits manipuliert sie diese, indem sie die Zeichen am Bildschirm darstellt sowie Eingaben und/oder Löschvorgänge des Benutzers auf den String überträgt. Sie stellt eine Art „Tor“ zu den „Zeilen“ dar. Als kleines Anwendungsbeispiel wollen wir einen „Mini-Editor“ schreiben, der eine jTextArea -Komponente verwaltet. Als „Leckerbissen“ wollen wir den darin enthaltenen Text – laden und speichern. Wir entwerfen unseren Editor am Bildschirm, indem wir geeignete Buttons auf einer jPanel-Komponente am oberen Bildschirmrand platzieren und eine jTextArea -Komponente den Rest des Formulars ausfüllen lassen. Dafür wählen wir als Layout des Formulars das BorderLayout. Die Buttons dienen zum Speichern, Laden, Löschen des Textes. Als Beispiel dient ein weiterer Button zum Ermitteln der Zeilenzahl im Textfeld. Die jTextArea-Komponente nennen wir editor. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow Wir gehen der Reihe nach vor: Löschen: S. 28 Beim Klicken des Buttons neu … private void bNeuActionPerformed(java.awt.event.ActionEvent evt) { editor.setText(""); } Laden: private void bLadenActionPerformed(java.awt.event.ActionEvent evt) { try vorgegebener Dateiname { editor.read(new FileReader("test.txt"),null); } catch(Exception ex){javax.swing.JOptionPane.showMessageDialog(null, "Fehler beim Dateizugriff!");} } Damit das klappt: import java.io.*; vor die Klasse stellen! Der Editor liest den Inhalt einer Datei namens test.txt, die von einem FileReaderObjekt bereitgestellt wird. Dabei kann es zu Exceptions kommen („Die Datei gibt es gar nicht“, …), die in einem try..catchKonstrukt abgefangen werden müssen. Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 29 Speichern: private void bSpeichernActionPerformed(java.awt.event.ActionEvent evt) { try { editor.write(new FileWriter("test.txt")); } catch(Exception ex){javax.swing.JOptionPane.showMessageDialog(null, "Fehler beim Dateizugriff!");} } Der Editor schreibt seinen Inhalt in eine Datei namens test.txt, die von einem FileWriterObjekt bereitgestellt wird. Dabei kann es zu Exceptions kommen („Datenträger schreibgeschützt“, …), die in einem try..catch-Konstrukt abgefangen werden müssen. Textzeilen erzeugen und einfügen: Editorinhalt kopieren und zählen Das kann eine TextArea schon von alleine! Einfach losschreiben! Zeilen zählen: Wir kopieren den Editorinhalt in eine Hilfsvariable h und zählen die Anzahl der Zeilenvorschübe darin: private void bZaehlenActionPerformed(java.awt.event.ActionEvent evt) { String h = editor.getText(); int zeilen = 0; for(int i=0;i<h.length();i++) if(h.charAt(i)=='\n') zeilen++; javax.swing.JOptionPane.showMessageDialog(null,"insgesamt "+zeilen+" Zeilen im Textfeld!"); } Virtuelle Lehrerweiterbildung Informatik in Niedersachsen Java-Anwendungen und Zeichenketten Eckart Modrow S. 30 8.6 Aufgaben 1. Ersetzen Sie die vier Knöpfe des Minieditors durch ein Menü. 2. Ergänzen Sie das Programm so, dass bei Programmende eine Warnung erscheint, wenn veränderte Texte noch nicht gespeichert wurden. 3. Unterscheiden Sie im Menü die Punkte Speichern und Speichern-Unter in der üblichen Weise. Geben Sie dazu einen Standard-Dateinamen für neue Texte vor, der beim Speichern durch den selbst gewählten ersetzt wird. Zeigen Sie den aktuellen Dateinamen in der Kopfleiste des Fensters an.