3. Kommandozeile
• Stammt direkt vom
Teletype-Arbeitsplatz ab:
• Anfrage wird
eingegeben
• Antwort wird
ausgedruckt
4. public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Gib den Namen Deiner Katze ein.");
String correctAnswer = "Telefonmann";
String input = in.readLine();
while (!correctAnswer.equals(input)) {
System.out.println("Das ist doch kein Name für eine Katze!");
input = in.readLine();
}
System.out.println("Ist besser.");
}
Gib den Namen Deiner Katze ein.
Peter
Das ist doch kein Name für eine Katze!
Orang-Utan Klaus
Das ist doch kein Name für eine Katze!
Telefonmann
Ist besser.
5. Kommandozeile
• Die dialogorientierte Schnittstelle, bei der
Dinge nacheinander abgefragt werden, ist
etwas aus der Mode.
• Kommandozeilen sind aber nach wie vor
Teil jedes Betriebssystems und vieler
komplexer Softwarepakete (z.B. MATLAB).
8. Visuelle Sprache
• Von unterschiedlichen GUI-Elementen wird
per Konvention ein bestimmtes Verhalten
erwartet, zum Beispiel
• Checkbox
• Radiobutton
9. Bibliothek
• GUI-Elemente werden von einer Bibliothek
bereitgestellt, die mehr oder weniger zur
verwendeten Plattform gehört:
• Windows, Mac OS X, Android, iPhone
• Linux hat zwei: Qt und GTK
• Java hat zwei: Swing und SWT
10. Know your library
• Es führt kein Weg daran vorbei, die
Dokumentation der jeweiligen Bibliothek
zu lesen.
• Dafür bekommt man viel Funktionalität frei
Haus, und außerdem Entscheidungen
abgenommen.
• Meistens gibt es auch noch ein Style Guide.
12. API
• Die dokumentierte Schnittstelle, über die
die Anwendungssoftware mit der Plattform
kommuniziert, nennt man API (Application
Programming Interface).
• Besteht grob aus Befehlen (was ich mit der
Plattform tun kann) und Events (was mir
von der Plattform aus passieren kann).
13. Befehle
• Füge in die Linke obere Ecke des Fensters
einen Knopf mit der Aufschrift a ein.
• Ändere den Text, der im Textfeld x
angezeigt wird, zu y.
• Lies den Text aus, den der Benutzer in das
Eingabefeld e eingegeben hat.
14. Events
• Ein Event (Ereignis) wird dem Programm
signalisiert, sobald etwas interessantes
passiert:
• Benutzer klickt mit der Maus auf Knopf x.
• Eine Email kommt.
• Eine Zeitspanne t ist abgelaufen.
• Der Rechner wird heruntergefahren.
15. Komponenten
• In einer GUI-Bibliothek mit einer
objektorientierten API sind die GUI-Elemente
Objekte, mit denen diese Dinge getan
werden.
• Für alle Standard-GUI-Elemente werden
Klassen bereitgestellt. Um ein Element mit
spezialisiertem Verhalten zu erzeugen, muss
eine eigene Klasse erstellt werden.
16. Konkret: Swing
• Komponentenklassen fangen mit J an.
• Zum Beispiel
• JButton (ein Druckknopf)
• JFrame (ein “großes” Fenster mit allem
drum und dran)
• JPanel (eine Fläche, auf der andere
Komponenten angeordnet sind)
17. Komponenten sind
Container
• In viele Komponenten kann man andere
Komponenten hineintun.
• Ein JPanel zum Beispiel kann andere
Komponenten aufnehmen und auf
unterschiedliche Arten anordnen.
18. GridLayout layout = new GridLayout(2,1);
JPanel panel = new JPanel(layout);
JButton button = new JButton("Klick mich");
panel.add(button);
JButton button2 = new JButton("Oder mich");
panel.add(button2);
19. LayoutManager
• Die LayoutManager ermöglichen es,
Komponenten koordinatenfrei, regelbasiert
anzuordnen.
• Ein bisschen wie HTML: Dort gibt man ja
auch nicht absolut vor, was wo stehen soll,
sondern erlaubt dem Browser, die Dinge so
anzuordnen, dass sie passen. Sollte man
jedenfalls.
20. Deklarative GUI
• ... und in der Tat gibt es GUI-Frameworks, in
denen man die Oberfläche nicht prozedural
zusammenprogrammiert, sondern in einer
XML-Datei beschreibt.
• ... was dann auch wiederum ein graphisches
Werkzeug tun kann.
• Swing gehört nicht dazu.
21. Beinahe deklarative
GUI
• Trotzdem sollte der Code, der die GUI
aufbaut, sich wie eine Seitenbeschreibung
lesen. Er soll nur die GUI-Elemente
zusammenstöpseln und sonst nichts.
• Es gibt sogar graphische GUI-Builder, die
solchen Code generieren. Z.B. NetBeans.
22. GridLayout
• Ordnet mehrere Dinge kachelförmig an
• mit wählbarer Reihen-/Spaltenzahl
• und macht alle Elemente gleich groß
23. BorderLayout
• Hat eine Mittelkomponente und je eine
linke/rechte/obere/untere Komponente.
• Mittelkomponente ist so groß, wie sie kann.
• Randkomponenten sind so groß, wie sie
müssen.
• Perfekt für: Anwendungsprogramme mit
Werkzeugleisten oder dergleichen.
25. Layout Hints
• Der LayoutManager einer Komponente
wird über zusätzliche Parameter beim
Hinzufügen der Elemente bedient, die
spezifisch für den Layout-Manager sind.
contentPane.setLayout(new BorderLayout());
contentPane.add(panel, BorderLayout.NORTH);
contentPane.add(text, BorderLayout.CENTER);
26. JLabel
• Ein JLabel ist ein einfaches Textfeld, dessen
Inhalt vom Programm gesetzt werden kann.
label = new JLabel(“Hallo.”,SwingConstants.CENTER);
contentPane.add(label, BorderLayout.CENTER);
... anderswo:
label.setTest(“Tschüß.”);
27. Events
• In einer objektorientierten GUI-Bibliothek
kommen die Events bei den Komponenten-
Objekten an, denen sie passiert sind.
• Zum Beispiel bei einem Knopf: Dass er
gedrückt wurde.
• Oder bei einem Fenster: Dass seine Größe
geändert wurde.
28. Konkret: Swing
• Komponenten delegieren die Bearbeitung
der Events, die bei ihnen ankommen, an
Listener-Objekte, die bei ihnen registriert
werden können.
• Am Listener-Objekt wird dann von der
Komponente eine bestimmte Interface-
Methode aufgerufen und ein Event-Objekt
übergeben, in dem steht, was passiert ist.
29. ...
JButton button = new JButton("Klick mich");
button.setActionCommand("knopf1");
button.addActionListener(this);
panel.add(button);
JButton button2 = new JButton("Oder mich");
button2.setActionCommand("knopf2");
button2.addActionListener(this);
panel.add(button2);
...
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("knopf1")) {
clickCounter++;
text.setText(labelText());
} else if (e.getActionCommand().equals("knopf2")) {
clickCounter--;
text.setText(labelText());
}
}
31. Problem
• In Event-Handlern darf man keine lang
dauernden Dinge tun. Nichts ausrechnen,
keine Dateien einlesen, nichts.
• Sonst sieht der Benutzer einen
eingefrorenen Bildschirm und denkt, es ist
etwas kaputt.
• Das ist nicht spezifisch für Swing, sondern
gibt es in ähnlicher Form immer.
32. Problem
• Das Problem ist sogar ernster: In einem
ActionListener in einer Schleife mehrmals
ein Textfeld aktualisieren geht überhaupt
nicht, weil Swing erst nach Ausstieg aus
dem ActionListener dazu kommt, das
Textfeld neu zu malen.
• Das Problem ist also mehr als kosmetisch.
33. Lösung: SwingWorker
• Eine Klasse, die “etwas zu tun” darstellt.
• Eigene Unterklasse erzeugen.
• In doInBackground() die Arbeit machen und
regelmäßig publish() aufrufen.
• In process() die GUI aktualisieren.
• Dann muss man nichts weiter über Threads
wissen.
34. class PrimeNumbersTask extends SwingWorker<List<Integer>,Integer> {
PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
//initialize
}
@Override
public List<Integer> doInBackground() {
while (! enough && ! isCancelled()) {
number = nextPrimeNumber();
publish(number);
}
return numbers;
}
@Override
protected void process(List<Integer> chunks) {
for (int number : chunks) {
textArea.append(number + "n");
}
}
}