Paint - Objektorientiert

Werbung
Paint - Objektorientiert
DVG3 - Paint - Objektorientiert
1
Bisheriger Ansatz
DVG3 - Paint - Objektorientiert
2
Alles in einem großen Programm (über 700 Zeilen, 20 KByte).
Programm weiß Alles, steuert Alles.
Programm wird sehr unübersichtlich.
Um die Programmlänge zu begrenzen, wird Programmtext mehrfach
verwendet.
Es entstehen Abhängigkeiten, die nicht inhaltlich erforderlich sind.
Erweiterungen, Modifikationen, Korrekturen sind schwierig und
haben oft Auswirkungen auf andere Programmbereiche und funktionen.
Weiterentwicklung ist nur mit hohem Aufwand möglich und außerdem
sehr fehleranfällig.
Bestimmte Funktionen (z.B. Korrekturen auf der Ebene von
graphischen Objekten, Vergrößern oder Verkleinern des Bildes) sind
kaum oder nur mit sehr hohem Aufwand realisierbar.
Objektorientierter Ansatz
DVG3 - Paint - Objektorientiert
3
Hauptprogramm ist zuständig für:
das Layout (Buttons, Labels, LayoutMenagar u.s.w.)
die Programminitialisierung (Einstellen der Standardwerte,
Erzeugen des ersten graphischen Objektes u.s.w.)
den Programmablauf (Reaktion auf Buttons, Checkboxen u.s.w.)
die Programmbeendigung (Abspeichern geänderter Bilder)
DVG3 - Paint - Objektorientiert
4
Jedes graphische Teil (Punkt, Linie, Oval, Rechteck u.s.w.) stellt ein
Objekt einer speziellen Klasse dar.
Graphische Objekte sind zuständig für:
die Behandlung von Mausereignissen
ihre graphische Darstellung in endgültiger bzw. in grober Form.
die Bereitstellung von Hilfetexten
ihre Identifizierung im Statusbereich
die Erzeugung des Protokolltextes
die Bereitstellung eines Nachfolgeobjektes
ihre Speicherung in einer Liste alle graphischen Objekte
ihre Transformation
Alle graphischen Objekte müssen diese Funktionen realisieren.
Alle graphischen Objekte realisieren diese Funktionen verschieden.
 Alle Klassen für graphische Objekte werden von einer Elternklasse
abgeleitet.
Die Klasse PaintableObject
import java.awt.Graphics;
import java.io.Serializable;
import java.awt.event.MouseEvent;
DVG3 - Paint - Objektorientiert
5
public
{
public
public
public
public
public
public
public
public
public
public
public
public
}
abstract class PaintableObject implements Serializable
abstract void paint(Graphics g, Paint parent);
void raw(Graphics g, Paint parent){ paint(g, parent); }
void transform(double x0, double y0, double mx, double my){}
String getCommand(){ return toString(); }
String help(){ return "No Help available!"; }
PaintableObject mouseClicked(MouseEvent e){return this;}
PaintableObject mousePressed(MouseEvent e){return this;}
PaintableObject mouseDragged(MouseEvent e){return this;}
PaintableObject mouseReleased(MouseEvent e){return this;}
PaintableObject mouseMoved(MouseEvent e){return this;}
PaintableObject mouseEntered(MouseEvent e){return this;}
PaintableObject mouseExited(MouseEvent e){return this;}
Abstrakte Klasse, da paint nicht implementiert wurde.
DVG3 - Paint - Objektorientiert
6
Alle anderen Methode wurden implementiert mit trivialen Methoden,
oder als leere Methode.
Es sind alle Methoden von MouseListener und
MouseMotionListener implementiert. Unterschied: Die Methoden
geben ein PaintableObject zurück um:
Sich selbst aktiv zu halten, wenn sie noch nicht alle Inforationen
zusammenbekommen haben oder
Ein neues PaintableObjekt zu erzeugen und an das
Hauptprogramm zurückzugeben.
Das Interface Serializable ist implementiert, damit die Objekte in
einen ObjectOutputStream geschrieben bzw. von einem
ObjectInputStream gelesen werden können.
Die Klasse PaintPoint
DVG3 - Paint - Objektorientiert
7
import
import
import
public
{
java.awt.Graphics;
java.awt.Panel;
java.awt.event.MouseEvent;
class PaintPoint extends PaintableObject
public double x0;
// Koordinaten des Punktes
public double y0;
private transient Paint f;
//transient, damit f und p
private transient Panel p;
//nicht gespeichert werden
PaintPoint(Paint f, Panel p)
{
this.f=f;
this.p=p;
f.writeMessage(help(0));
f.writeTool("point");
}
//Hilfetext ausgeben
//Status anzeigen
DVG3 - Paint - Objektorientiert
8
public PaintableObject mouseReleased(MouseEvent e)
{
x0 = e.getX();
//Koordinaten speichern
y0 = e.getY();
paint(f.g0, f);
//in Bild zeichnen
p.paint(p.getGraphics()); //Bild neuzeichnen
f.writeProt(getCommand()); //Protokoll schreiben
f.appendGraph(this);
//Objekt speichern
return new PaintPoint(f,p);//neuen Punkt zurückgeben
}
public void transform
(double x0, double y0, double mx, double my)
{
this.x0=x0+mx*this.x0;
//Punkt transformieren
this.y0=y0+my*this.y0;
}
public String toString()
{
return "PaintPoint : x0 = " //Zeichenkette ausgeben
+(int)Math.round(x0)+"; y0 = "+(int)Math.round(y0);
}
public void paint(Graphics g, Paint parent)
{
g.fillOval(
//Punkt Zeichnen
(int)Math.round(x0-1),(int)Math.round(y0-1),3,3);
}
DVG3 - Paint - Objektorientiert
9
public String getCommand()
{
return "g.fillOval("+ //Protokoll erzeugen
(int)Math.round(x0-1)+","+
(int)Math.round(y0-1)+",3,3);\n";
}
public String help(int step)
{
return "Punkt setzen!";
}
}
//help-Text ausgeben
Die Klasse Paint
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
DVG3 - Paint - Objektorientiert
10
public class Paint extends Frame implements
MouseListener, MouseMotionListener, WindowListener,
ActionListener, ItemListener, ComponentListener
{
public static void main(String[] args)
{ new Paint("Paint"); }
... // globale Attribute
... // Konstruktor
... // Definition des Layouts, der Buttons u.s.w.
... // Hilfsmethoden
... // WindowListener
... // ActionListener
DVG3 - Paint - Objektorientiert
11
public void actionPerformed(ActionEvent e){
char command = e.getActionCommand().charAt(0);
switch (command)
{
case 'e': dispose();
case 'd': pObject=new PaintPoli(this,gPanel,false); break;
case 'p': pObject=new PaintPoint(this,gPanel);
break;
case 'l': pObject=new PaintLine(this,gPanel);
break;
case 'r': pObject=new PaintRect(this,gPanel);
break;
case 'o': pObject=new PaintOval(this,gPanel,false); break;
case 'c': pObject=new PaintOval(this,gPanel,true); break;
case 'n': pObject=new PaintRoundRect(this,gPanel); break;
case '3': pObject=new Paint3DRect(this,gPanel);
break;
case 'a': pObject=new PaintArc(this,gPanel);
break;
case 'b': pObject=new PaintPoli(this,gPanel,true); break;
case 's': graph.writeFile(this);
break;
case 'm': graph.readFile(this,g0);
graph.paint(g0,this);
gPanel.paint(gPanel.getGraphics());
break;
case 'i': pObject = new PaintImage(this,gPanel,lastPO);
break;
}
if (! (pObject instanceof PaintImage) ) lastPO=pObject;
}
//MouseListener, MouseMotionListener
public void mouseEntered(MouseEvent e){
pObject=pObject.mouseEntered(e);}
public void mouseExited(MouseEvent e){
pObject=pObject.mouseExited(e);
}
DVG3 - Paint - Objektorientiert
public void mouseClicked(MouseEvent e){
pObject=pObject.mouseClicked(e);}
public void mousePressed(MouseEvent e){
pObject=pObject.mousePressed(e);}
public void mouseDragged(MouseEvent e){
pObject=pObject.mouseDragged(e);
showStatus(e.getX(),e.getY());
}
public void mouseReleased(MouseEvent e){
pObject=pObject.mouseReleased(e);}
public void mouseMoved(MouseEvent e){
pObject=pObject.mouseMoved(e);
12
showStatus(e.getX(),e.getY());
}
Überarbeitung
DVG3 - Paint - Objektorientiert
13
Vereinfachungen:
Die Konstruktoren der graphischen Objekte haben zwei
Parameter:
• Paint parent – Paintobjekt, das das graphische Objekt
enthält
• Panel gPanel – Panel, in das gezeichnet werden soll
gPanel ist aber in parent bekannt, kann also bei geeigneter
Wahl der Zugriffsrechte aus parent bestimmt werden. Dieser
Parameter kann also eingespart werden.
• gPanel.paint(...)  parent.gPanel.paint(...)
• Graphik-Kontexte von gPanel (onScreen) und offImage
(offScreen) werden häufig benötigt
 friendly Attribute in Paint:
Graphics onGraphics
Graphics offGraphics
Das Attribut PaintableObject pObject (actualObject)
zeigt auf das nächste zu bearbeitende Objekt.
 actualObject friendly
 Listener-Methoden können actualObject direkt setzen
 actualObject braucht nicht als Wert zurückgegeben zu
werden.
DVG3 - Paint - Objektorientiert
14
Konsequente Überprüfung der Zugriffsrechte public, private und
"friendly".
Realisierung von Funktionen, die in allen von PaintableObject
benötigten Funktionen in PaintableObject, z.B.:
Definition des Attributes parent
Speichern des Attributes parent
Ausgabe des Help-Textes
Anzeige des Tool-Status
public abstract class PaintableObject implements Serializable
{
transient Paint parent;
public PaintableObject(Paint parent)
{
this.parent = parent;
parent.writeMessage(help());
//Hilfetext ausgeben
parent.writeTool(tool());
//Status anzeigen
}
Klassifzierung
PaintLine, PaintRect, Paint3DRect, PaintRoundRect und
PaintOval sind ähnlich:
DVG3 - Paint - Objektorientiert
Gemeinsamkeiten:
• Zwei charakteristische Punkte
• Transformations-Methoden sind gleich
• Art des Zeichnens: Maus mit gedrückter Taste vom ersten zum
zweiten Punkt ziehen und Taste dann loslassen.
• Helptexte z.T. gleich
Unterschiede:
• PaintLine hat keinen Füllmodus
• Paint3DRect hat raised-Modus
• PaintOval besitzt Kreis-Modus
• Paint-Methoden, Tool-Bezeichnungen, toString-Methoden,
getCommand-Methoden sind unterschiedlich
Wir definieren eine abstrakte Klasse Paint2Point als Elternklasse
für die genannten Klassen.
15
Paint2Point
DVG3 - Paint - Objektorientiert
16
import java.awt.event.MouseEvent;
public abstract class Paint2Point extends PaintableObject
{
double x0, y0;
double x1, y1;
Paint2Point(Paint parent){
super(parent);
}
public void mousePressed(MouseEvent e) {
x0=e.getX();
y0=e.getY();
}
public void mouseDragged(MouseEvent e) {
x1=e.getX();
y1=e.getY();
parent.gPanel.paint(parent.onGraphics);
raw(parent.onGraphics);
}
DVG3 - Paint - Objektorientiert
17
public void mouseReleased(MouseEvent e) {
x1=e.getX();
y1=e.getY();
paint(parent.offGraphics);
parent.gPanel.paint(parent.onGraphics);
parent.writeProt(getCommand());
parent.appendGraph(this);
}
public void transform
(double x0, double y0, double mx, double my) {
this.x0=x0+mx*this.x0;
this.x1=x0+mx*this.x1;
this.y0=y0+my*this.y0;
this.y1=y0+my*this.y1;
}
public String help() {
return "Erste Ecke eingeben und Maus mit gedrueckter"
+" Taste zur gegenueberliegende Ecke bewegen!";
}
}
PaintLine
DVG3 - Paint - Objektorientiert
18
import java.awt.Graphics;
import java.awt.event.MouseEvent;
public class PaintLine extends Paint2Point
{
PaintLine(Paint parent) {
super(parent);
}
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
parent.actualObject= new PaintLine(parent);
}
public String toString() {
return "PaintLine : x0 = "+(int)Math.round(x0)+
"; y0 = "+(int)Math.round(y0)+"; x1 = "+
(int)Math.round(x1)+"; y1 = "+(int)Math.round(y1);
}
public void paint(Graphics g) {
g.drawLine((int)Math.round(x0),(int)Math.round(y0),
(int)Math.round(x1),(int)Math.round(y1));
}
DVG3 - Paint - Objektorientiert
19
public String getCommand() {
return "g.drawLine("+(int)Math.round(x0)+","+
(int)Math.round(y0)+","+(int)Math.round(x1)+","+
(int)Math.round(y1)+");\n";
}
public String help() {
return "Anfangspunkt eingeben und Maus mit gedrueckter "+
"Taste zum Endpunkt bewegen!";
}
public String tool(){ return "line"; }
}
Paint3DRect
DVG3 - Paint - Objektorientiert
20
import java.awt.Graphics;
import java.awt.event.MouseEvent;
public class Paint3DRect extends Paint2Point
{
private boolean fill;
private boolean raise;
public Paint3DRect (Paint parent){
super(parent);
}
public void mousePressed(MouseEvent e){
super.mousePressed(e);
fill=parent.fillMode;
raise=parent.raiseMode;
}
public void mouseReleased(MouseEvent e){
super.mouseReleased(e);
parent.actualObject= new Paint3DRect(parent);
}
DVG3 - Paint - Objektorientiert
21
public String toString(){...}
public void paint(Graphics g){
int x=(int)Math.round(Math.min(x0,x1));
int y=(int)Math.round(Math.min(y0,y1));
int w=(int)Math.round(Math.abs(x0-x1));
int h=(int)Math.round(Math.abs(y0-y1));
if (fill) g.fill3DRect(x,y,w,h,raise);
else g.draw3DRect(x,y,w,h,raise);
}
public void raw(Graphics g){
int x=(int)Math.round(Math.min(x0,x1));
int y=(int)Math.round(Math.min(y0,y1));
int w=(int)Math.round(Math.abs(x0-x1));
int h=(int)Math.round(Math.abs(y0-y1));
g.draw3DRect(x,y,w,h,raise);
}
public String getCommand(){...}
}
Kombination von graphischen Objekten
DVG3 - Paint - Objektorientiert
22
Das gesamte Bild besteht aus der Kombination von einzelnen
graphischen Objekten.
Das gesamte Bild ist andererseits ein (komplexes) graphisches
Objekt. Es hat die gleichen Eigenschaften wie ein einfaches Objekt.
Es kann gezeichnet werden (paint, raw)
Es kann transformiert werden.
Das gesamte Bild wird als Liste von einfachen graphischen Objekten
eingerichtet.
Dadurch dass PaintGraph von PaintableObject abgeleitet wird, kann
die Gruppierungsfunktion realisiert werden.
DVG3 - Paint - Objektorientiert
23
public class PaintGraph extends PaintableObject
{
private LinkedList list = new LinkedList();
private static String saveDirectory = "";
public PaintGraph(Paint parent){ super(parent); }
public void append(PaintableObject po){
list.addLast(po);
}
public void paint(Graphics g){
Object le;
for (int i=0;i<list.size();i++ )
{
le = list.get(i);
((PaintableObject)le).paint(g);
}
}
public void raw(Graphics g){
Object le;
for (int i=0;i<list.size();i++ )
{
le = list.get(i);
((PaintableObject)le).raw(g);
}
}
DVG3 - Paint - Objektorientiert
24
public String toString(){
return list.toString();
}
public void transform (double x0, double y0, double mx, double my){
Object le;
for (int i=0;i<list.size();i++ )
{
((PaintableObject)(list.get(i))).transform(x0,y0,mx,my);
}
}
DVG3 - Paint - Objektorientiert
25
public void writeFile(){
FileDialog fd =
new FileDialog(parent,"Select Output File",FileDialog.SAVE);
fd.setDirectory(saveDirectory);
fd.setVisible(true);
saveDirectory = fd.getDirectory();
String fileName = saveDirectory+fd.getFile();
try
{
ObjectOutputStream out =
new ObjectOutputStream(
new FileOutputStream(fileName));
out.writeObject(parent.getBounds());
out.writeObject(list);
out.close();
}
catch(Exception e)
{
System.err.println(e);
}
}
DVG3 - Paint - Objektorientiert
26
public void readFile(Graphics g)
{
FileDialog fd = new FileDialog
(parent,"Select Input File",FileDialog.LOAD);
fd.setDirectory(saveDirectory);
fd.setVisible(true);
saveDirectory = fd.getDirectory();
String fileName = saveDirectory+fd.getFile();
ObjectInputStream in = null;
try
{
in = new ObjectInputStream(
new FileInputStream(fileName));
Rectangle rect = (Rectangle)in.readObject();
list = (LinkedList)in.readObject();
in.close();
parent.resize(rect);
PaintableObject le;
for (int i=0;i<list.size();i++ )
{
le=(PaintableObject)(list.get(i));
le.parent=parent;
le.paint(g);
}
}
catch(Exception e)
{
e.printStackTrace();
}
DVG3 - Paint - Objektorientiert
27
}
}
Herunterladen