Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2015 Prof. Dr. Nitsche Übung 8 – Beispiellösung Ereignis-Bearbeitung und Threads Aufgabe 1: Ereignis-Bearbeitung und Layout-Manager a) Layouten Sie ein Fenster mit einem Zeichenpanel (für die Spieldarstellung) und zwei Buttons (z.B. „Neues Spiel“ und „Ende“). b) Implementieren Sie eine einfache Ereignis-Bearbeitung für die beiden Buttons. (Geben Sie beispielsweise jeweils einen Button-spezifischen Text aus.) Implementieren Sie dazu jeweils • passende actionPerformed-Methoden in inneren Klassen (oder als anonyme Klassen) • und registrieren Sie Objekte dieser Klassen bei den Buttons als ActionListener. c) Reagieren Sie ferner auf Mausklicks im Zeichenpanel. (Geben Sie beispielsweise die Position der Maus aus.) Implementieren Sie dazu eine passende mouseClicked-Methode und registrieren Sie diese als MouseListener beim Zeichenpanel. Hinweis: Dazu müssen Sie auch noch – wenn auch ggf. als leere Methode – die anderen Methoden des Interfaces MouseListener implementieren. Hinweis: Die Klick-Position der Maus erfahren Sie durch event.getPoint(). d) Nicht ausgelastet? Reagieren Sie auch auf Tastatureingaben im Fenster. (So sollten z.B. beim Drücken der Tasten „N“ bzw. „E“ die gleiche Reaktion wie beim Klicken auf die entsprechenden Buttons erfolgen. Sie können auch auf die Ziffern 1..9 reagieren, um Eingaben (wie das gewählte Feld im Spiel TicTacToe) von Tastatur steuern zu können. Implementieren Sie dazu eine passende keyTyped-Methode und registrieren Sie diese als KeyListener beim Zeichenpanel. Hinweis: Damit das Panel auf Ihre Eingaben reagiert, müssen Sie es mit setFocusable(true) „fokus-fähig“ machen. Die jeweils gedrückte Taste können Sie dann mit keyEvent.getKeyChar() abfragen. S. 1 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 e) Nicht ausgelastet? Erweitern Sie die Ereignis-Bearbeitung derart, dass bei Änderung der Fenstergröße automatisch auch die Spielobjekte (Kreise und Kreuze) in ihrer Größe angepasst werden. Hinweis: Über die Änderung der Größe einer GUI-Komponente können Sie sich durch die ComponentListener-Methode componentResized informieren lassen. games.examples.ticTacToe.TicTacToe.java: package games.examples.ticTacToe.ueb8_aufg1; import games.basic.gameObjects.interfaces.GameObject; import import import import import import import import java.awt.BorderLayout; java.awt.Color; java.awt.event.ActionEvent; java.awt.event.ActionListener; java.awt.event.MouseEvent; java.awt.event.MouseListener; java.util.ArrayList; java.util.Scanner; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class TicTacToe implements ActionListener { public static final int GAP = 5; private ArrayList<GameObject> components = new ArrayList<GameObject>(); private int componentSize = 60; private int xframesize = componentSize*3 + 10; private int yframesize = componentSize*3 + 30; JFrame frame; private JButton newButton; private JButton endeButton; private TicPanel ticPanel; private boolean isKreuz = true; enum Spieler { LEER, KREUZ, KREIS }; Spieler spielFeld[][] = new Spieler[3][3]; private void newGame() { S. 2 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 for (int feldX = 0; feldX < 3; feldX++) { for (int feldY = 0; feldY < 3; feldY++) { spielFeld[feldX][feldY] = Spieler.LEER; } } ticPanel.clearGameObjects(); } public static void main(String[] args) { TicTacToe prog = new TicTacToe(); prog.run(); } public void run() { JFrame frame = new JFrame("Tic Tac Toe"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); newButton = new JButton("Neues Spiel"); endeButton = new JButton("Ende"); newButton.addActionListener(this); endeButton.addActionListener(this); JPanel buttonPanel = new JPanel(); ticPanel = new TicPanel(); ticPanel.setBackground( Color.darkGray); ticPanel.addMouseListener( new TicMouseListener()); newGame(); frame.add( BorderLayout.CENTER, ticPanel); frame.add( BorderLayout.SOUTH, buttonPanel); buttonPanel.add(newButton); buttonPanel.add(endeButton); frame.setVisible(true); frame.setSize(xframesize, yframesize); // // // // // // // Kreuz k = new Kreuz(0, 1, getFeldBreite(), getFeldHoehe()); ticPanel.addGameObject(k); Kreis k2 = new Kreis(1, 1, getFeldBreite(), getFeldHoehe()); ticPanel.addGameObject(k2); frame.repaint(); } S. 3 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 @Override public void actionPerformed(ActionEvent e) { System.out.println("actionPerformed: " + e.getActionCommand()); if (e.getSource() == newButton) { System.out.println("Neues Spiel starte ..."); } else if (e.getSource() == endeButton){ System.out.println("Ende des Spiels ..."); } } private class TicMouseListener implements MouseListener { @Override public void mouseClicked(MouseEvent e) { System.out.println("mouseClicked"); int x = e.getX(); int y = e.getY(); System.out.println("Mausklick: x = " + x + ", y = " + y); int breite = ticPanel.getWidth(); int hoehe = ticPanel.getHeight(); int feldX = x / (breite/3); int feldY = y / (hoehe/3); System.out.println("Feld: x = " + feldX + ", y = " + feldY); GameObject temp; if(isKreuz) { temp = new Cross(feldX, feldY, breite / 3, hoehe / 3); isKreuz = false; } else { temp = new Dot(feldX, feldY, breite / 3, hoehe / 3); isKreuz = true; } ticPanel.addGameObject(temp); ticPanel.repaint(); } @Override public void mouseEntered(MouseEvent e) { System.out.println("mouseEntered"); } @Override public void mouseExited(MouseEvent e) { System.out.println("mouseExited"); } @Override public void mousePressed(MouseEvent e) { S. 4 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 System.out.println("mousePressed"); } @Override public void mouseReleased(MouseEvent e) { System.out.println("mouseReleased"); } } } games.examples.ticTacToe.TicPanel.java: package games.examples.ticTacToe.ueb8_aufg1; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import javax.swing.JPanel; import java.awt.Color; import java.awt.Graphics; import games.basic.gameObjects.interfaces.*; class TicPanel extends JPanel { private List<GameObject> gameObjects = new LinkedList<GameObject>(); public void addGameObject(GameObject gameObj) { gameObjects.add(gameObj); } public void clearGameObjects() { gameObjects.clear(); } public TicPanel(List<GameObject> gameObjects) { this.gameObjects = gameObjects; } public TicPanel() {} // --> this.gameObjects = // new LinkedList<GameObject>(); @Override public void paintComponent(Graphics g) { int breite = this.getWidth(); S. 5 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik int hoehe Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 = this.getHeight(); // Zeichne Trennlinien für 3x3-Feld g.setColor(Color.black); g.drawLine(0, hoehe/3, breite, hoehe/3); g.drawLine(0, hoehe/3*2, breite, hoehe/3*2); g.drawLine(breite/3, 0, breite/3, hoehe); g.drawLine(breite/3*2, 0, breite/3*2, hoehe); g.drawRect(0, 0, breite-1, hoehe-1); //this.setBorder( new LineBorder(Color.blue)); // Zeichne Komponenten for( GameObject gameObj : gameObjects) { if (gameObj instanceof Cross) { // Kreuz ((Cross) gameObj).resize(breite / 3, hoehe / 3); } if (gameObj instanceof Dot) { // Kreis ((Dot) gameObj).resize(breite / 3, hoehe / 3); } gameObj.paintComponent(g); } } } // class TicPanel games.examples.ticTacToe.Cross.java: package games.examples.ticTacToe.ueb8_aufg1; import java.awt.Color; import games.basic.gameObjects.CrossGameObject; import games.basic.position.interfaces.Positionable; import games.basic.position.Position; public class Cross extends CrossGameObject { private int feldX; private int feldY; public static final Color CROSS_COLOR = Color.red; private static final int GAP = TicTacToe.GAP; public Cross(int feldX, int feldY, int breite, int hoehe) { super(new Position(feldX * breite +GAP, feldY * hoehe +GAP), breite - GAP*2, hoehe - GAP*2, S. 6 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 CROSS_COLOR, false); //System.out.println("Cross: feldX = "+ feldX // + ", feldY = " + feldY // + ", width = " + breite // + ", height = " + hoehe); this.feldX = feldX; this.feldY = feldY; } public Cross(int feldX, int feldY, int size) { this(feldX, feldY, size, size); } public void resize(int breite, int hoehe) { this.setWidth(breite - GAP*2); this.setHeight(hoehe - GAP*2); this.setPos(feldX * breite +GAP, feldY * hoehe +GAP); } } games.examples.ticTacToe.Dot.java: package games.examples.ticTacToe.ueb8_aufg1; import games.basic.gameObjects.CircularGameObject; import games.basic.position.interfaces.Positionable; import games.basic.position.Position; import java.awt.Color; import java.awt.Graphics; public class Dot extends CircularGameObject { private int feldX; private int feldY; public static final Color CIRC_COLOR = Color.blue; private static final int GAP = TicTacToe.GAP; public Dot(int feldX, int feldY, int breite, int hoehe) { super(new Position(feldX * breite +GAP, feldY * hoehe +GAP), Math.min(breite, hoehe) - GAP*2, CIRC_COLOR, false); this.feldX = feldX; this.feldY = feldY; } public Dot(int feldX, int feldY, int size) { this(feldX, feldY, size, size); } S. 7 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik // Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 public void resize(int breite, int hoehe) { this.setRadius(Math.min(breite, hoehe) / 2); this.setRadius(Math.min(breite, hoehe) - GAP*2); this.setPos(feldX * breite +GAP, feldY* hoehe +GAP); } } Aufgabe 2: Tic Tac Toe Implementieren Sie das Spiel Tic Tac Toe. Tic Tac Toe (auch „Drei gewinnt“ oder „Kreis und Kreuz“) ist ein Spiel für zwei Personen. Dabei machen auf einem 3×3 Felder großen Spielfeld die beiden Spieler abwechselnd ihre Zeichen (ein Spieler Kreuze, der andere Kreise). Der Spieler, der als erstes drei seiner Zeichen in eine Reihe, Spalte oder eine der beiden Hauptdiagonalen setzen kann, gewinnt. [wikipedia] Erweitern Sie dazu die grafische Darstellung für das Spiel Tic Tac Toe um die Spielverwaltung. Dabei sollen geeignete Spielobjekte jeweils (rote) Kreuze sowie (blaue) Kreise zur Darstellung der Züge der beiden Gegner verwendet werden. a) Sie müssen sich dazu den jeweils aktuellen Spielstand merken: • Wer ist gerade am Zug: rot oder blau? • Welche Felder sind bereits belegt und von wem? Darüber hinaus macht es Sinn, eine Liste von Spielobjekten (List<GameObject>) zu verwalten, welche die jeweils auf dem Zeichenpanel darzustellenden Spielobjekte enthält. (Bei jedem Zug wird dabei ein Feld belegt und ein zugehöriges Spielobjekt zur grafischen Darstellung erzeugt.) b) Passen Sie die Ereignisbearbeitung aus Aufgabe 1 derart an, dass jetzt b) Der Button „Neu Starten“ das Spiel neu startet, d.h. alle Spielobjekte löscht und das Spielfeld als leer initialisiert. c) Der Button „Ende“ das gesamte Programm (mit System.exit) beendet. d) Der Nutzer im laufendem Spiel durch Klicken mit der Maus innerhalb des Zeichenpanels jeweils ein (noch nicht belegtes) Spielfeld auswählen kann, in welches das nächste Spielobjekte (Kreis oder Kreuz) gesetzt wird. S. 8 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 Hinweis: Zum Neuzeichnen des Fensters können Sie die Methode frame.repaint() aufrufen. c) Überprüfen Sie nach jedem Spielzug, b) ob ein Gegner alle 3 Felder einer Zeile, Spalte oder Diagonale besetzt hält (dann hat er gewonnen), c) oder alle 9 Felder besetzt sind (dann ist das Spiel unentschieden ausgegangen). d) oder das Spiel mit dem nächsten Zug weitergeht. Alt – SS 2010 (TicTacToe) package exercises.gui.ttt; import java.awt.Color; import games.basic.gameObjects.CircularGameObject; public class Kreis extends CircularGameObject { private int feldX; private int feldY; private int breite; private int hoehe; public Kreis(int feldX, int feldY, int breite, int hoehe) { super(feldX * breite, feldY * hoehe, Math.min(breite, hoehe) / 2, Color.blue, 2); // System.out.println("Kreis: feldX = "+ feldX + ", feldY = " + feldY + ", breite = " + breite + ", hoehe = " + hoehe); this.feldX = feldX; this.feldY = feldY; this.breite = breite; this.hoehe = hoehe; } public void resize(int breite, int hoehe) { this.breite = breite; this.hoehe = hoehe; this.setRadius(Math.min(breite, hoehe) / 2); this.setPos(feldX * breite, feldY * hoehe); } } package exercises.gui.ttt; import java.awt.Color; import games.basic.gameObjects.CrossGameObject; S. 9 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 public class Kreuz extends CrossGameObject { private int feldX; private int feldY; private int breite; private int hoehe; public Kreuz(int feldX, int feldY, int breite, int hoehe) { super(feldX * breite, feldY * hoehe, breite, hoehe, Color.red, 2); // System.out.println("Kreuz: feldX = "+ feldX + ", feldY = " + feldY + ", breite = " + breite + ", hoehe = " + hoehe); this.feldX = feldX; this.feldY = feldY; this.breite = breite; this.hoehe = hoehe; } public void resize(int breite, int hoehe) { this.breite = breite; this.hoehe = hoehe; this.setWidth(breite); this.setHeight(hoehe); this.setPos(feldX * breite, feldY * hoehe); } } package exercises.gui.ttt; import javax.swing.JPanel; import javax.swing.border.LineBorder; import java.awt.Graphics; import java.awt.Color; import java.util.List; import java.util.LinkedList; import games.basic.gameObjects.interfaces.GameObject; public class TicPanel extends JPanel { private List<GameObject> gameObjects = new LinkedList<GameObject>(); public void addGameObject(GameObject gameObj) { gameObjects.add(gameObj); } S. 10 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 public void clearGameObjects() { gameObjects.clear(); } @Override public void paintComponent(Graphics g) { int breite = this.getWidth(); int hoehe = this.getHeight(); g.setColor(Color.blue); g.drawLine(0, hoehe/3, breite, hoehe/3); g.drawLine(0, hoehe/3*2, breite, hoehe/3*2); g.drawLine(breite/3, 0, breite/3, hoehe); g.drawLine(breite/3*2, 0, breite/3*2, hoehe); g.drawRect(0, 0, breite-1, hoehe-1); //this.setBorder( new LineBorder(Color.blue)); for( GameObject gameObj : gameObjects) { if (gameObj instanceof Kreuz) { ((Kreuz) gameObj).resize(breite / 3, hoehe / 3); } if (gameObj instanceof Kreis) { ((Kreis) gameObj).resize(breite / 3, hoehe / 3); } gameObj.paintComponent(g); } } } package exercises.gui.ttt; import games.basic.gameObjects.interfaces.GameObject; import java.awt.BorderLayout; import java.awt.Color; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class Tic implements ActionListener { public static void main(String[] args) { S. 11 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 Tic tic = new Tic(); tic.run(); } private JFrame frame; private JButton newButton; private JButton endeButton; private TicPanel ticPanel; TicMouseListener ticMouseListener; private boolean isKreuz = true; private Spieler winner = Spieler.LEER; // currently no winner enum Spieler { LEER, KREUZ, KREIS }; Spieler spielFeld[][] = new Spieler[3][3]; private void newGame() { for (int feldX = 0; feldX < 3; feldX++) { for (int feldY = 0; feldY < 3; feldY++) { spielFeld[feldX][feldY] = Spieler.LEER; } } ticPanel.clearGameObjects(); ticPanel.addMouseListener( ticMouseListener ); isKreuz = true; frame.repaint(); } private boolean isEnd() { // Prüfe auf Spielende for (int zeile = 0; zeile < 3; zeile++) { if (spielFeld[zeile][0] == spielFeld[zeile][1] && spielFeld[zeile][0] == spielFeld[zeile][2] && spielFeld[zeile][0] != Spieler.LEER) { winner = spielFeld[zeile][0]; // Gewinner return true; } } for (int spalte = 0; spalte < 3; spalte++) { if (spielFeld[0][spalte] == spielFeld[1][spalte] && spielFeld[0][spalte] == spielFeld[2][spalte] && spielFeld[0][spalte] != Spieler.LEER) { winner = spielFeld[0][spalte]; // Gewinner return true; } } // Diagonalen if (spielFeld[0][0] == spielFeld[1][1] && spielFeld[0][0] == spielFeld[2][2] && spielFeld[0][0] != Spieler.LEER) { winner = spielFeld[0][0]; // Gewinner S. 12 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 return true; } if (spielFeld[0][2] == spielFeld[1][1] && spielFeld[0][2] == spielFeld[2][0] && spielFeld[0][2] != Spieler.LEER) { winner = spielFeld[0][2]; return true; } Prof. Dr. Nitsche Übung 8 // Gewinner // Prüfe auf unentscheiden winner = Spieler.LEER; for (int feldX = 0; feldX < 3; feldX++) { for (int feldY = 0; feldY < 3; feldY++) { if (spielFeld[feldX][feldY] == Spieler.LEER) return false; // Spiel noch nicht zuende } } return true; // Spiel zuende, alle Felder belegt } private int getFeldBreite() { return ticPanel.getWidth() / 3; } private int getFeldHoehe() { return ticPanel.getHeight() / 3; } public void run() { frame = new JFrame("Tic Tac Toe"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); newButton = new JButton("Neues Spiel"); endeButton = new JButton("Ende"); newButton.addActionListener(this); endeButton.addActionListener(this); JPanel buttonPanel = new JPanel(); // ticPanel = new TicPanel(); ticPanel.setBackground( Color.darkGray); ticMouseListener = new TicMouseListener(); ticPanel.addMouseListener( ticMouseListener ); // in newGame() newGame(); frame.add( BorderLayout.CENTER, ticPanel); frame.add( BorderLayout.SOUTH, buttonPanel); buttonPanel.add(newButton); buttonPanel.add(endeButton); S. 13 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 frame.setVisible(true); frame.setSize(400, 400); frame.repaint(); } // // // --- ActionListener ---------------------------------------------------@Override public void actionPerformed(ActionEvent e) { System.out.println("actionPerformed: " + e.getActionCommand()); if (e.getSource() == newButton) { System.out.println("Neues Spiel starte ..."); this.newGame(); } else if (e.getSource() == endeButton){ System.out.println("Ende des Spiels ..."); System.exit(0); } } private int getBreite() { return ticPanel.getWidth(); } // --- MouseListener ---------------------------------------------------private class TicMouseListener implements MouseListener { // // // @Override public void mouseClicked(MouseEvent e) { System.out.println("mouseClicked"); int x = e.getX(); int y = e.getY(); System.out.println("Mausklick: x = " + x + ", y = " + y); int breite = ticPanel.getWidth(); int hoehe = ticPanel.getHeight(); int feldX = x / (breite/3); int feldY = y / (hoehe/3); System.out.println("Feld: x = " + feldX + ", y = " + feldY); if (spielFeld[feldX][feldY] == Spieler.LEER) { // nur, falls Feld noch nicht belegt GameObject temp; if(isKreuz) { temp = new Kreuz(feldX, feldY, breite / 3, hoehe / 3); spielFeld[feldX][feldY] = Spieler.KREUZ; isKreuz = false; } else { temp = new Kreis(feldX, feldY, breite / 3, hoehe / 3); spielFeld[feldX][feldY] = Spieler.KREIS; S. 14 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 isKreuz = true; } ticPanel.addGameObject(temp); ticPanel.repaint(); if (isEnd()) { String msg = "Spiel beendet. "; if (winner == Spieler.LEER) msg += "Unentschieden"; else msg+= "Gewinner = " + winner; System.out.println(msg); JOptionPane.showMessageDialog(frame, msg, "Ende", JOptionPane.INFORMATION_MESSAGE); // verhindere weitere Eingaben, bis neues Spiel startet ticPanel.removeMouseListener(ticMouseListener); } } else { System.out.println("Feld bereits belegt!"); } } @Override public void mouseEntered(MouseEvent e) { System.out.println("mouseEntered"); } // @Override public void mouseExited(MouseEvent e) { System.out.println("mouseExited"); } // @Override public void mousePressed(MouseEvent e) { System.out.println("mousePressed"); } // @Override public void mouseReleased(MouseEvent e) { System.out.println("mouseReleased"); } // } } S. 15 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 Aufgabe 3: Erzeugen und Starten von Threads a) Sei BankKunde eine von einer Klasse Kunde abgeleitete Klasse. Erweitern Sie die Klasse BankKunde derart, dass Bankkunden nebenläufig als Java-Threads operieren können. Als Thread-Operation soll 50-mal „Jetzt arbeitet <Kunde>“ ausgegeben werden, wobei <Kunde>der Name des Kunden ist. b) Erzeugen und starten Sie zwei BankKunden-Threads dagobert und donald. c) Analysieren Sie die Ausgabe des Programms. Starten Sie dazu das Programm mehrmals hintereinander. Ist die Ausgabe jeweils gleich, oder können Sie Unterschiede im Programmablauf erkennen? Hinweis: Sie können die Ausgabe auch zu „Jetzt arbeitet <Kunde> zum <i>-ten Mal“ abändern, um evtl. stärkere Effekte zu beobachten. Alt – SS 2010 (Threads) exercises.threads.bankKunde.Kunde.java package exercises.threads.bankKunde; public class Kunde { private String name; public Kunde(String name) { this.name = name; } public String getName() { return this.name; } } exercises.threads.bankKunde.BankKunde.java package exercises.threads.bankKunde; public class BankKunde extends Kunde implements Runnable { public BankKunde(String name) { super(name); } public static void main(String args[]) { S. 16 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 // Erzeuge und starte Threads dagobert und donald BankKunde kundeDagobert = new BankKunde("Dagobert"); Thread threadDagobert = new Thread( kundeDagobert ); threadDagobert.start(); BankKunde kundeDonald = new BankKunde("Donald"); Thread threadDonald = new Thread( kundeDonald ); threadDonald.start(); } // Erweiterung um Thread-Methode(n) public void run() { for (int i = 0; i < 50; i++) { System.out.println("Jetzt arbeitet " + this.getName()); } } } S. 17 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 Aufgabe 4: Bewegung von Objekten In vielen Spielen (z.B. in Pong) sollen sich Bälle und andere Spielobjekte auf dem Bildschirm (d.h. in einem Fenster) kontinuierlich bewegen. a) Überlegen Sie sich mögliche Realisierungen, um ein (Spiel)objekt auf dem Bildschirm bewegt zu können. b) Was sind mögliche Probleme Ihrer jeweiligen Lösungsvorschläge? c) Nicht ausgelastet? Implementieren Sie die Bewegung eines Kreises als Spielobjekt in einem Fenster. S. 18 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 Zusatz-Aufgabe 5 (für Java-Experten): Java-Rätsel Was macht das folgende Programm? public class Workout { public static void main(String[] args) { workHard(); System.out.println("Es ist Zeit für eine Pause."); } private static void workHard() { try { workHard(); } finally { workHard(); } } } Lösung: • • • Läuft sehr lange : o 1 + 2 + 4 + 8 + … + 21.024 = 21.025 – 1 rekursive Aufrufe, o 21.024 Exceptions o Z.B. bei ca. 1010 Aufrufen/Sekunde, 1010 Exception/Sekunde 1,7 ⋅ 10291 Jahre (vgl: Sonne = 1010 Jahre alt) bei – je nach JVM – 1024 rekursiven Aufrufen StackOverflowError jeweils abgefangen durch finally erneuter Rekursionsaufruf S. 19 / 20 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2012 Prof. Dr. Nitsche Übung 8 S. 20 / 20