Übungsblatt 13 - Lösungsvorschlag

Werbung
Universität Augsburg, Institut für Informatik
Prof. Dr. Werner Kießling
M. Endres, A. Huhn, T. Preisinger
Sommersemester 2006
27. Juli. 2006
Lösungsblatt 13
Informatik II
Aufgabe 1: Stoppuhr
Stopwatch.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Stopwatch extends JComponent implements ActionListener {
Segment sec = new Segment(), secD = new Segment(),
min = new Segment(), minD = new Segment();
JButton btnStart = new JButton("Start"), btnStop = new JButton("Stop");
StopwatchThread thread;
public Stopwatch() {
setLayout(new BorderLayout());
JPanel pnlValue = new JPanel(new GridLayout());
pnlValue.add(minD); pnlValue.add(min);
pnlValue.add(new Segment(Segment.MINUS));
pnlValue.add(secD); pnlValue.add(sec);
JPanel pnlControl = new JPanel();
pnlControl.add(btnStart);
pnlControl.add(btnStop);
add(pnlValue, BorderLayout.CENTER);
add(pnlControl, BorderLayout.PAGE_END);
btnStop.setEnabled(false);
btnStart.addActionListener(this);
btnStop.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if (src == btnStart) {
// Start gedrückt
btnStart.setEnabled(false);
btnStop.setEnabled(true);
// Thread starten
thread = new StopwatchThread();
thread.start();
} else if (src == btnStop) {
btnStart.setEnabled(true);
btnStop.setEnabled(false);
// Thread "anhalten"
thread.pleaseStop();
thread = null;
}
}
1
public void setTime(int seconds) {
sec.setValue(seconds % 10);
seconds = seconds / 10;
secD.setValue(seconds % 6);
seconds = seconds / 6;
min.setValue(seconds % 10);
seconds = seconds / 10;
minD.setValue(seconds % 10);
repaint();
}
class StopwatchThread extends Thread {
boolean cont = true;
long startTime;
StopwatchThread() { this.setDaemon(true); }
public void pleaseStop() { cont = false; }
public void run() {
startTime = System.currentTimeMillis();
while (cont) {
// neuen Zählerstand berechnen und setzen
int seconds = (int) (System.currentTimeMillis() - startTime) / 1000;
setTime(seconds);
// ... und warten
try { sleep(1000);} catch (InterruptedException e) {}
}
}
}
}
StopwatchApplet.java
import javax.swing.JApplet;
import javax.swing.JFrame;
public class StopwatchApplet extends JApplet {
public void init() {
add(new Stopwatch());
validate();
}
}
stopwatch.html
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<title>Counter</title>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
</head>
<body>
<object classid="java:blatt13.StopwatchApplet"
type="application/x-java-applet" height="200"
width="450" codebase="file:."/>
</body>
</html>
2
Aufgabe 2: Fortschrittsanzeige mit Java 2D
ProgressCircle.java
import java.awt.*;
import javax.swing.JComponent;
public class ProgressCircle extends JComponent {
// Minimum, Maximum und aktueller Wert
int min, max, value;
public ProgressCircle(int min, int max, int value) {
this.min = min;
this.max = max;
this.value = value;
}
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Stroke standard = g2d.getStroke();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Dimension dim = getSize();
// Breite und Höhe verringern, damit der Kreis komplett sichtbar ist.
int width = (int) dim.getWidth() - 1;
int height = (int) dim.getHeight() - 1;
// Aussenkreis zeichnen
g2d.drawOval(0, 0, width, height);
// Innenkreis zeichnen
// Zuerst Pinselfarbe ändern
g2d.setPaint(new GradientPaint(0, 0, Color.YELLOW, width, height,
Color.RED));
// Größentransformation und Translation durchführen
double scaleFactor = ((double) value / max - min);
g2d.translate(width / 2 * (1 - scaleFactor), height / 2
* (1 - scaleFactor));
g2d.scale(scaleFactor, scaleFactor);
g2d.fillOval(1, 1, width - 2, height - 2);
}
public void setValue(int value) { this.value = value; }
}
ProgressCircleApplet.java
public class ProgressCircleApplet extends JApplet {
JSlider slider = new JSlider(0, 100, 0);
ProgressCircle circle = new ProgressCircle(0, 100, 0);
public void init() {
setLayout(new BorderLayout());
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
circle.setValue(slider.getValue());
circle.repaint();
}
});
3
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setMajorTickSpacing(10);
slider.setMinorTickSpacing(2);
add(circle, BorderLayout.CENTER);
add(slider, BorderLayout.PAGE_END);
}
}
Aufgabe 3: Erzeuger und Verbraucher in der Mensa
Mensa.java
import java.util.*;
import java.util.concurrent.Semaphore;
public class Mensa {
public static void main(String[] args) {
// Theke mit entsprechender Kapazität anlegen
Theke theke = new Theke(100);
// Threads initialisieren
Angestellter[] personal = new Angestellter[5];
for (int i = 0; i < personal.length; i++) {
personal[i] = new Angestellter(theke, i);
}
Student[] esser = new Student[100];
for (int i = 0; i < esser.length; i++) { esser[i] = new Student(theke);}
// Threads starten
for (Angestellter a : personal) a.start();
for (Student s : esser) s.start();
// Alle 2,5 Sekunden ausgeben, wie viele Personen im letzten
// Intervall maximal warten mussten
while (true) {
// Maximal wartende ausgeben
System.out
"
.println("\t\tMAXIMALE ZAHLEN: \n\t\t\tWartende Studenten:
+ theke.maxStudenten
+ "\n\t\t\tWartende Angestellte: "
+ theke.maxAngestellte
+ "\n\t\tWartezeit im Durchschnitt bei insgesamt "
+ theke.anzahlWarteVorgaenge
+ " Wartenden:\n\t\t\t"
+ ((theke.kummulierteWartezeit / 1000.0)
/ theke.anzahlWarteVorgaenge));
// Werte zurücksetzen
theke.maxAngestellte = 0;
theke.maxStudenten = 0;
try { Thread.sleep(2500); } catch (InterruptedException e) {;}
}
}
}
4
class Theke {
/**
* Sowohl für die verfügbaren Mahlzeiten als auch für die verfügbaren Plätze
* auf der Theke sind Semaphore notwendig: Es darf nicht passieren, dass
* weniger als 0 oder mehr als 100 Plätze auf der Theke belegt (also
* Mahlzeiten verfügbar) sind.
*/
// Semaphor für die verfügbaren Mahlzeiten
Semaphore mahlzeit;
// Semaphor für die verfügbaren Plätze
Semaphore platz;
// die wartenden Personen
Vector<Angestellter> wartendeAngestellte = new Vector<Angestellter>();
Vector<Student> wartendeStudenten = new Vector<Student>();
// die maximale Anzahl wartender Angestellter und Studenten
int maxAngestellte;
int maxStudenten;
// Wartezeit
long kummulierteWartezeit;
int anzahlWarteVorgaenge;
public Theke(int kapazitaet) {
mahlzeit = new Semaphore(0, true);
platz = new Semaphore(kapazitaet, true);
}
public void tablettAblegen(Angestellter a) throws InterruptedException {
// Angestellter beginnt Warten - auf maximale Anzahl Wartender prüfen
wartendeAngestellte.add(a);
if (wartendeAngestellte.size() > maxAngestellte)
maxAngestellte = wartendeAngestellte.size();
System.out.println("TA -start- Wartend (Studenten/Angestellte): (" +
wartendeStudenten.size() + "/" + wartendeAngestellte.size() + "), " +
"Verfügbare Mahlzeiten: " + mahlzeit.availablePermits());
// 50 Plätze auf der Theke belegen
platz.acquire(50);
// 50 Mahlzeiten zur Abholung durch Studenten freigeben
mahlzeit.release(50);
//
wartendeAngestellte.remove(a);
System.out.println("TA - end - Wartend (Studenten/Angestellte): (" +
wartendeStudenten.size() + "/" + wartendeAngestellte.size() + "), " +
"Verfügbare Mahlzeiten: " + mahlzeit.availablePermits());
}
public void essenNehmen(Student s) throws InterruptedException {
wartendeStudenten.add(s);
if (wartendeStudenten.size() > maxStudenten)
maxStudenten = wartendeStudenten.size();
System.out.println("EN -start- Wartend (Studenten/Angestellte): (" +
wartendeStudenten.size() + "/" + wartendeAngestellte.size() + "), " +
"Verfügbare Mahlzeiten: " + mahlzeit.availablePermits());
long start = System.currentTimeMillis();
// eine Mahlzeit nehmen
mahlzeit.acquire(1);
5
// Wartezeitberechnung
kummulierteWartezeit += System.currentTimeMillis() - start;
anzahlWarteVorgaenge++;
// einen Platz auf der Theke als frei markieren
platz.release(1);
// Student aus der Liste der Wartenden entfernen
wartendeStudenten.remove(s);
System.out.println("EN - end - Wartend (Studenten/Angestellte): (" +
wartendeStudenten.size() + "/" + wartendeAngestellte.size() + "), " +
"Verfügbare Mahlzeiten: " + mahlzeit.availablePermits());
}
}
class Student extends Thread {
Theke theke;
public Student(Theke theke) { this.theke = theke; }
public void run() {
while (true) {
try {
// eine Mahlzeit von der Theke nehmen
theke.essenNehmen(this);
// Wartezeit
sleep(2000);
} catch (InterruptedException e) {;}
}
}
}
class Angestellter extends Thread {
Theke theke;
int nummer;
public Angestellter(Theke theke, int nummer) {
this.theke = theke;
this.nummer = nummer;
}
public void run() {
while (true) {
try {
// neue Mahlzeiten auf die Theke legen
theke.tablettAblegen(this);
// Wartezeit
sleep(5000);
} catch (InterruptedException e) {;}
}
}
}
6
Herunterladen