View.java
(vorläufig)
package algorithmen.umleditor;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
/**
* Basisklasse aller Views von UML-Objekten.
* Enthält das Modell und die Position
* (= linke obere Ecke des umgebenden Rechtecks)
* Die Größe ergibt sich aus dem Modell.
*/
abstract public class View implements Serializable {
protected Point pos;
protected UmlElement model;
protected Dimension size; // aus den Strings berechnet und gecached
/** Abstand zwischen Strings oder Strings und Linien in Pixel */
protected int sepSize = 5;
/** div. Font, werden lazy initialisiert,
* da dazu Graphics-Objekt nötig */
protected Font standardFont;
protected Font cursiveFont;
protected Font boldFont;
protected Font curBoldFont;
/**
* Erzeugt einen View für das model an der Position p.
*/
public View(UmlElement model, Point p) {
this.model = model;
pos = p;
size = new Dimension();
// Liste der Observer bereitmachen
observers = new Vector();
}
/**
* Zeichnet das Objekt.
*/
abstract public void draw(Graphics g);
/**
* Erzeugt einen Editor für das Objekt.
* Er ist modal bzgl. des angegebenen Frames bzw. Dialogs.
*/
abstract public Editor createEditor(UmlElement m, Frame p);
abstract public Editor createEditor(UmlElement m, Dialog p);
/**
* Erzeugt ein Standard-UmlElement.
* Dies ist Teil des FactoryMethod Patterns und wird verwendet, damit
* der ListEditor neue Elemente verschiedenen Typs erzeugen kann.
*/
abstract public UmlElement createStandardObject();
/**
* Holt die aktuelle Position eines Objekts.
*/
public Point getPosition() {
return pos;
}
/**
* Setzt die aktuelle Position eines Objekts.
*/
public void setPosition(Point p) {
pos = p;
notifyObservers();
}
/**
* Holt das aktuelle Modell des Views.
*/
public UmlElement getModel() {
return model;
}
/**
* Setzt das aktuelle Modell des Views.
*/
public void setModel(UmlElement m) {
model = m;
notifyObservers();
}
/**
* Holt die Größe des Objekts.
* Gesetzt wird die Größe vom View selbst durch Bestimmung der Teile,
* nicht von außen vorgegeben.
*/
public Dimension getSize() {
return size;
}
/**
* Prüft, ob der Punkt p im umschließenden Rechteck des Objekts liegt.
*/
public boolean contains(Point p) {
Rectangle r = new Rectangle(pos, size);
return r.contains(p);
}
/**
* Verschiebt das Objekt um (dx, dy).
*/
public void translate(int dx, int dy) {
pos.translate(dx, dy);
notifyObservers();
}
// Hilfsmethoden
/**
* Gibt die Höhe von Strings bezogen auf den verwendeten Font zurück.
*/
protected int getStringHeight(Graphics g) {
return g.getFontMetrics().getHeight();
}
/**
* Gibt die Breite eines Strings bezogen auf den verwendeten Font zurück.
*/
protected int getStringWidth(String s, Graphics g) {
return g.getFontMetrics().stringWidth(s);
}
/**
* Fonts "lazy" initialisieren
*/
protected void initFonts(Graphics g) {
if (standardFont == null) {
standardFont = g.getFont();
cursiveFont = standardFont.deriveFont(Font.ITALIC);
boldFont = standardFont.deriveFont(Font.BOLD);
curBoldFont = standardFont.deriveFont(Font.ITALIC | Font.BOLD);
}
}
// Infrastruktur für das Observer-Pattern
/** Liste der Observer */
protected Vector observers;
/**
* Registriert einen Observer.
*/
public synchronized void addObserver(Observer o) {
observers.addElement(o);
}
/**
* Löscht einen Observer aus der Liste.
*/
public synchronized void deleteObserver(Observer o) {
observers.removeElement(o);
}
/**
* Informiert alle Observer.
*/
public void notifyObservers() {
Vector l;
// Klone die Liste der Listener, damit sich Benachrichtigung und evtl.
// Änderungen an den Listenern (add/delete) nicht stören.
synchronized (this) {
l = (Vector) observers.clone();
}
for (int i = 0; i < l.size(); i++) {
((Observer) l.elementAt(i)).update();
}
}
}