/*
* Datei: Vis.java
* Autor(en): Lukas K�nig
* Java-Version: 6.0
* Erstellt (vor): 14.11.2008
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/
package fmg.fmg8.pfeilGUI;
import fmg.fmg8.graphVis.zeichenModi.AusgMerkm;
import fmg.fmg8.graphVis.zeichenModi.Geometrie2D;
import fmg.fmg8.graphVis.zeichenModi.Kreis2D;
import fmg.fmg8.graphVis.zeichenModi.PfeilMaster;
import fmg.fmg8.graphVis.zeichenModi.Pfeilspitze;
import fmg.fmg8.graphVis.zeichenModi.Pol2DMitAusgMerkm;
import fmg.fmg8.graphVis.zeichenModi.Polygon2D;
import fmg.fmg8.graphVis.zeichenModi.SegSpez;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.statistik.Parametersatz;
import fmg.fmg8.statistik.logging.AbstractMsg;
import fmg.fmg8.statistik.logging.MsgError;
import fmg.fmg8.statistik.logging.MsgWarning;
import fmg.fmg8.umgebung2D.Vektor2D;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* Applet zur Visualisierung eines Graphen.
*
* @author Lukas K�nig.
*/
public class ZeichFen extends Frame implements MouseWheelListener {
/**
* Am 14.09.06 generiert.
*/
private static final long serialVersionUID = -4078048087117840970L;
/**
* Objekt, das die Polygone (u. �.) zur Darstellung eines Graphen erzeugt.
*/
private PfeilMaster zeichenArt;
/**
* Die benutzerdefinierten Segmentbeschreibungen.
*/
private LinkedList<SegSpez> userSegs;
/**
* Der Name des von <code>this</code> dargestellten Graphen.
*/
private String robName;
/**
* Die Dicken.
*/
private ArrayList<Double> dicken = new ArrayList<Double>();
/**
* Der Anfang des Pfeils.
*/
private Pfeilspitze anfang;
/**
* Das Ende des Pfeils.
*/
private Pfeilspitze ende;
/**
* Multiplikativer Faktor f�r die Gr��e des Pfeilanfangs.
*/
private double anfFakt;
/**
* Multiplikativer Faktor f�r die Gr��e des Pfeilendes.
*/
private double endFakt;
/**
* Die Parameter.
*/
private Parametersatz pars;
/**
* Die ID.
*/
private int id;
/**
* Das Pfeilpolygon.
*/
private Polygon2D pfeilPol;
/**
* Ob die Eckpunkte markiert werden sollen.
*/
private boolean markiereEcken = true;
/**
* Ob der Grundpfeil gezeichnet werden soll.
*/
private boolean zeichneGrundPfeil = true;
/**
* @return Returns the id.
*/
public int getId() {
return this.id;
}
/**
* Der angeklickte Punkt.
*/
private Vektor2D vekClick;
/**
* Die aktuelle Dicke.
*/
private double aktDicke;
/**
* Der erste markierte Knoten.
*/
private Integer mark1;
/**
* Der zweite markierte Knoten.
*/
private Integer mark2;
/**
* Die Segmentbeschreibungen.
*/
private SegSpez[] segBeschr;
/**
* Erste Ecke.
*/
private Vektor2D ersteEcke;
/**
* Zweite Ecke.
*/
private Vektor2D zweiteEcke;
/**
* beliebig gro�e Liste von markierten Knoten.
*/
private LinkedList<Integer> markierte;
/**
* Die Stufe des zuletzt aufgetretenen Fehlers.
*/
private int fehlerStufe = 0;
/**
* Die Skalierung im Verh�ltnis zur Normskalierung der Zeichenfl�che.
*/
private double skalierung;
/**
* Die Verschiebung der Grafik.
*/
private Vektor2D verschiebung;
/**
* Gr��e der Strichelung.
*/
private double gestrichelt;
/**
* Das Elternpfeilcontroller-Fenster.
*/
private PfeilController elternMaster;
/**
* Die Ausgabemerkmale des gestrichelten Pfeils.
*/
private AusgMerkm[] gestricheltMerkm;
/**
* Ob der Punkt im PfeilPol enthalten ist.
*
* @param vek Der Punkt.
*
* @return null oder Zeiger auf das enthaltene Objekt.
*/
private Vektor2D containsPoint(final Vektor2D vek) {
final double epsilon = 5 / this.skalierung;
for (Vektor2D v : this.pfeilPol) {
if (v.distanz(vek) <= epsilon) {
return v;
}
}
return null;
}
/**
* Implementierung eines �berschriebenen Konstruktors. Die Graphen werden
* von der Festplatte geladen.
*
* @param fenstertitel Der als Titel anzuzeigende String.
* @param graphNam Der Name des aktuellen Graphen.
* Visualisierung geh�rt.
* @param params Der Parametersatz.
* @param ident Die Identit�tsnummer.
* @param vater Der Pfeilmastervater.
*/
public ZeichFen(
final String fenstertitel,
final String graphNam,
final Parametersatz params,
final int ident,
final PfeilController vater) {
super(fenstertitel);
this.gestrichelt = 0;
this.ende = PfeilMaster.KUGEL_ENDE;
this.anfang = PfeilMaster.EINFACHE_SPITZE_1;
this.anfFakt = 1;
this.endFakt = 1;
this.gestricheltMerkm = new AusgMerkm[2];
this.gestricheltMerkm[0] = new AusgMerkm(
Color.black,
Color.blue,
true,
true);
this.gestricheltMerkm[1] = new AusgMerkm(
Color.black,
Color.yellow,
true,
true);
this.elternMaster = vater;
this.elternMaster.setzeSegmentFarben(this.gestricheltMerkm);
this.skalierung = 1;
this.verschiebung = new Vektor2D(Vektor2D.NULL_VEKTOR);
this.markierte = new LinkedList<Integer>();
this.userSegs = new LinkedList<SegSpez>();
this.setSize(750, 700);
this.aktDicke = fmg.fmg8.graphVis.zeichenModi.Konstanten.PFEIL_DICKE;
this.pfeilPol = new Polygon2D();
this.pars = params;
this.zeichenArt = new PfeilMaster(this.pars);
this.segBeschr = new SegSpez[1000];
this.addMouseWheelListener(this);
this.addComponentListener(new ComponentListener() {
@Override
public void componentHidden(final ComponentEvent e) {
}
@Override
public void componentMoved(final ComponentEvent e) {
}
@Override
public void componentResized(final ComponentEvent e) {
ZeichFen.this.neuZeichnen();
}
@Override
public void componentShown(final ComponentEvent e) {
}
}
);
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(final MouseEvent event) {
Vektor2D vek = new Vektor2D(
(event.getX() - verschiebung.x) / skalierung,
(event.getY() - verschiebung.y) / skalierung);
Vektor2D neu;
if (ZeichFen.this.vekClick != null) {
for (int i = 0; i < ZeichFen.this.pfeilPol.size(); i++) {
if (ZeichFen.this.markierte.contains(i)) {
neu = new Vektor2D(ZeichFen.this.pfeilPol.get(i));
neu.add(vek);
neu.sub(ZeichFen.this.ersteEcke);
ZeichFen.this.pfeilPol.set(i, neu);
}
}
ZeichFen.this.vekClick
= ZeichFen.this.containsPoint(vek);
ZeichFen.this.ersteEcke = vek;
ZeichFen.this.neuZeichnen();
} else {
ZeichFen.this.zweiteEcke
= new Vektor2D(
(event.getX() - verschiebung.x) / skalierung,
(event.getY() - verschiebung.y) / skalierung);
ZeichFen.this.neuZeichnen();
}
}
});
this.addMouseListener(new MouseAdapter() {
public void mousePressed(final MouseEvent event) {
Vektor2D vek = new Vektor2D(
(event.getX() - verschiebung.x) / skalierung,
(event.getY() - verschiebung.y) / skalierung);
ZeichFen.this.ersteEcke = new Vektor2D(vek);
ZeichFen.this.vekClick
= ZeichFen.this.containsPoint(vek);
ZeichFen.this.mark1 = ZeichFen.this.mark2;
ZeichFen.this.mark2 = ZeichFen.this.pfeilPol.realIndexOf(
ZeichFen.this.vekClick);
if (ZeichFen.this.mark1 != null
&& ZeichFen.this.mark1 < 0) {
ZeichFen.this.mark1 = null;
}
if (ZeichFen.this.mark2 != null
&& ZeichFen.this.mark2 < 0) {
ZeichFen.this.mark2 = null;
}
if (ZeichFen.this.mark1 != null
&& !ZeichFen.this.markierte.contains(
ZeichFen.this.mark1)) {
ZeichFen.this.markierte.add(ZeichFen.this.mark1);
}
if (ZeichFen.this.mark2 != null
&& !ZeichFen.this.markierte.contains(
ZeichFen.this.mark2)) {
ZeichFen.this.markierte.add(ZeichFen.this.mark2);
}
}
public void mouseClicked(final MouseEvent event) {
Vektor2D vek = new Vektor2D(
(event.getX() - verschiebung.x) / skalierung,
(event.getY() - verschiebung.y) / skalierung);
if (event.getButton() == 3) {
skaliere();
zentriere();
return;
}
if (ZeichFen.this.containsPoint(vek) == null
&& (ZeichFen.this.mark1 != null
|| ZeichFen.this.mark2 != null
|| ZeichFen.this.markierte.size() > 0)) {
ZeichFen.this.markierte.clear();
ZeichFen.this.mark1 = null;
ZeichFen.this.mark2 = null;
} else {
if (ZeichFen.this.vekClick == null
&& event.getClickCount() >= 2) {
ZeichFen.this.pfeilPol.add(new Vektor2D(vek));
ZeichFen.this.dicken.add(ZeichFen.this.aktDicke);
}
}
}
public void mouseReleased(final MouseEvent event) {
if (ZeichFen.this.ersteEcke != null
&& ZeichFen.this.zweiteEcke != null) {
ZeichFen.this.mark1 = null;
ZeichFen.this.mark2 = null;
ZeichFen.this.markierte.clear();
for (Vektor2D v : ZeichFen.this.pfeilPol) {
if (v.istInRechteck(
ZeichFen.this.ersteEcke,
ZeichFen.this.zweiteEcke)) {
ZeichFen.this.markierte.add(
ZeichFen.this.pfeilPol.realIndexOf(v));
}
}
}
Collections.sort(ZeichFen.this.markierte, new IntComp());
if (ZeichFen.this.markierte.size() > 0) {
if (ZeichFen.this.mark1 == null) {
ZeichFen.this.mark1 = ZeichFen.this.markierte.get(0);
}
if (ZeichFen.this.mark2 == null) {
ZeichFen.this.mark2 = ZeichFen.this.markierte.get(
ZeichFen.this.markierte.size() - 1);
}
}
ZeichFen.this.ersteEcke = null;
ZeichFen.this.zweiteEcke = null;
ZeichFen.this.neuZeichnen();
}
});
this.addKeyListener(new KeyListener() {
/**
* Die Key-Typed-Methode.
*/
public void keyTyped(final KeyEvent e) {
// throw new RuntimeException("Taste wurde gedr�ckt.");
}
/**
* Die Key-Released-Methode.
*/
public void keyReleased(final KeyEvent e) {
// throw new RuntimeException("Taste wurde losgelassen.");
}
/**
* Die Key-Pressed-Methode.
*/
public void keyPressed(final KeyEvent e) {
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_C) {
if (e.isControlDown()) {
SonstMeth.log(
SonstMeth.LOG_DEBUG,
"STRG-C",
ZeichFen.this.pars);
}
}
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_V) {
if (e.isControlDown()) {
SonstMeth.log(
SonstMeth.LOG_DEBUG,
"STRG-V",
ZeichFen.this.pars);
}
}
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_A) {
if (e.isControlDown()) {
ZeichFen.this.markiereAlle();
ZeichFen.this.neuZeichnen();
}
}
if (e.getKeyChar() == KeyEvent.VK_DELETE) {
ZeichFen.this.deleteMark();
ZeichFen.this.neuZeichnen();
}
}
});
}
/**
* Markiert alle Knoten.
*/
public void markiereAlle() {
for (int i = 0; i < this.pfeilPol.size(); i++) {
this.markierte.add(i);
}
Collections.sort(this.markierte, new IntComp());
if (this.markierte.size() > 0) {
this.mark1 = this.markierte.get(0);
this.mark2 = this.markierte.get(this.markierte.size() - 1);
}
}
/**
* L�scht alle markierten Knoten.
*/
public void deleteMark() {
for (int i : this.markierte) {
this.pfeilPol.remove(i);
for (int j = 0; j < this.markierte.size(); j++) {
if (this.markierte.get(j) >= i) {
this.markierte.set(j, this.markierte.get(j) - 1);
}
}
}
this.mark1 = null;
this.mark2 = null;
this.markierte.clear();
if (this.pfeilPol.size() <= 1) {
this.loescheSegs();
} else {
for (SegSpez s : this.segBeschr) {
if (s != null && s.getBeginn() >= this.pfeilPol.size()) {
s.setBeginn(this.pfeilPol.size() - 1);
}
if (s != null && s.getEnde() >= this.pfeilPol.size()) {
s.setEnde(this.pfeilPol.size() - 1);
}
}
}
}
/**
* Normalisieren.
*/
public void normalisiere() {
this.pfeilPol = this.pfeilPol.normalisiere();
if (this.dicken.size() < this.pfeilPol.size()) {
this.dicken.add(this.dicken.get(this.dicken.size() - 1));
}
}
/**
* Zeichnet den Graphen neu mit L�schen des Bildschirms.
*/
public void neuZeichnen() {
this.fehlerStufe = 0;
this.repaint();
}
/**
* Zeichnet den Graphen neu mit L�schen des Bildschirms.
*
* @param fehler Die Fehlerstufe.
*/
public void neuZeichnen(final int fehler) {
this.fehlerStufe = fehler;
this.repaint();
}
/**
* Setzt einen String, aber ber�cksichtigt das Kontrollzeichen '\n'.
*
* @param g
* Das Grafikobjekt.
* @param s
* Der String.
* @param x
* X-Koordinate.
* @param y
* Y-Koordinate.
*/
public void setzeString(final Graphics g, final String s, final int x,
final int y) {
int returnPos;
String schreibe;
String rest;
Font font;
if (s.length() > 0) {
font = g.getFont();
g.setFont(new Font("Monospaced", Font.BOLD, font.getSize()));
returnPos = s.indexOf("\n");
if (returnPos < 0) {
returnPos = s.length() - 1;
} else if (returnPos >= s.length()) {
returnPos = s.length() - 1;
}
schreibe = s.substring(0, returnPos);
rest = s.substring(returnPos + 1, s.length());
g.drawString(schreibe, x, y);
this.setzeString(g, rest, x, y + 14);
g.setFont(font);
}
}
/**
* L�scht alle aktuellen Segmente.
*/
private void loescheSegs() {
for (int i = 0; i < this.segBeschr.length; i++) {
this.segBeschr[i] = null;
}
}
/**
* F�gt eine Liste von Segmentbeschreibungen hinzu.
*
* @param segs Die Segmentbeschreibungen.
*/
private void addAllSegs(final List<SegSpez> segs) {
for (SegSpez s : segs) {
this.addSeg(s, true);
if (s.getBeginn() != 0) {
s.setPfeilAnfang(PfeilMaster.EINFACHER_ABSCHLUSS);
} else {
s.setPfeilAnfang(this.ende);
}
if (s.getEnde() != this.pfeilPol.size() - 1) {
s.setPfeilEnde(PfeilMaster.EINFACHER_ABSCHLUSS);
} else {
s.setPfeilEnde(this.anfang);
}
}
}
/**
* F�gt eine Segmentbeschreibung hinzu.
*
* @param neu Die neue Segmentbeschreibung.
* @param hinten Ob das Segment hinten (oder vorne) eingef�gt werden soll.
*/
private void addSeg(
final SegSpez neu,
final boolean hinten) {
int i = 0;
while (this.segBeschr[i] != null) {
i++;
}
if (!hinten) {
while (i > 0) {
this.segBeschr[i] = this.segBeschr[i - 1];
i--;
}
}
this.segBeschr[i] = neu;
}
/**
* Gibt eine Ampel als Kreise zur�ck.
*
* @param stufe 0 = gr�n, 1 = gelb, 2 = rot.
* @param linksOben Die Koordinaten der Mitte des oberen Lichts.
* @param radius Der Radius.
*
* @return Die Ampel als zeichenbare Liste.
*/
final ArrayList<Object> ampel(
final int stufe,
final Vektor2D linksOben,
final double radius) {
ArrayList<Object> liste = new ArrayList<Object>(6);
AusgMerkm ausgGRUENAktiv = new AusgMerkm(
Color.black, Color.green, true, true);
AusgMerkm ausgGELBAktiv = new AusgMerkm(
Color.black, Color.yellow, true, true);
AusgMerkm ausgROTAktiv = new AusgMerkm(
Color.black, Color.red, true, true);
AusgMerkm ausgGRUENPassiv = new AusgMerkm(
Color.black, new Color(200, 200, 200), true, true);
AusgMerkm ausgGELBPassiv = new AusgMerkm(
Color.black, new Color(200, 200, 200), true, true);
AusgMerkm ausgROTPassiv = new AusgMerkm(
Color.black, new Color(200, 200, 200), true, true);
Polygon2D quad = new Polygon2D(4);
Vektor2D xSub = new Vektor2D(radius * 1.5, 0);
Vektor2D ySub = new Vektor2D(0, radius * 1.5);
Vektor2D zwisch;
zwisch = new Vektor2D(linksOben);
zwisch.sub(xSub);
zwisch.sub(ySub);
quad.add(zwisch);
zwisch = new Vektor2D(linksOben.x, linksOben.y + radius * 4 + radius);
zwisch.sub(xSub);
zwisch.add(ySub);
quad.add(zwisch);
zwisch = new Vektor2D(linksOben.x, linksOben.y + radius * 4 + radius);
zwisch.add(xSub);
zwisch.add(ySub);
quad.add(zwisch);
zwisch = new Vektor2D(linksOben.x, linksOben.y);
zwisch.add(xSub);
zwisch.sub(ySub);
quad.add(zwisch);
AusgMerkm zwAusg = new AusgMerkm(Color.black, Color.black, true, true);
liste.add(zwAusg);
liste.add(quad.toPol(1, Vektor2D.NULL_VEKTOR));
Kreis2D k1 = new Kreis2D(
linksOben.x,
linksOben.y,
radius);
Kreis2D k2 = new Kreis2D(
linksOben.x,
linksOben.y + radius * 2 + radius / 2,
radius);
Kreis2D k3 = new Kreis2D(
linksOben.x,
linksOben.y + radius * 4 + radius,
radius);
if (stufe == 2) {
liste.add(ausgROTAktiv);
} else {
liste.add(ausgROTPassiv);
}
liste.add(k1);
if (stufe == 1) {
liste.add(ausgGELBAktiv);
} else {
liste.add(ausgGELBPassiv);
}
liste.add(k2);
if (stufe == 0) {
liste.add(ausgGRUENAktiv);
} else {
liste.add(ausgGRUENPassiv);
}
liste.add(k3);
return liste;
}
/**
* Verschiebt das Polygon um den angegebenen Vektor. Dabei werden alle
* Punkte des Polygons tats�chlich (und nicht nur relativ zur Zeichenfl�che
* versetzt.
*
* @param vek Der Verschiebevektor.
*/
public void verschiebe(final Vektor2D vek) {
this.pfeilPol.verschiebe(vek);
}
/**
* Gibt Kreise zur�ck, deren Mittelpunkte den Ortsvektoren der �bergebenen
* Nachrichten entsprechen. Falls Nachrichten ohne Ortsvektor als Zusatz
* existieren, werden sie ignoriert.
*
* @param liste Die Nachrichtenliste.
* @return Die Markierungskreise.
*/
private LinkedList<Kreis2D> fehlerQuellen(final List<AbstractMsg> liste) {
LinkedList<Kreis2D> kreise = new LinkedList<Kreis2D>();
final double radius = 10;
Vektor2D zwisch;
for (AbstractMsg m : liste) {
if (m.getZusatz() != null
&& m.getZusatz().getClass().equals(Vektor2D.class)) {
zwisch = new Vektor2D((Vektor2D) m.getZusatz());
zwisch.mult(skalierung);
zwisch.add(verschiebung);
kreise.add(new Kreis2D(zwisch, radius));
}
}
return kreise;
}
/**
* Erzeugt ein Polygon aus dem aktuellen Pfeil, das direkt als Spitze
* verwendet werden kann.
*
* @return Das Grundpolygon, das unabh�ngig von den Userpolygonen ist.
*/
public Polygon2D getGrundPolSpitze() {
if (this.pfeilPol.size() <= 0) {
return null;
}
Vektor2D versch = new Vektor2D(this.pfeilPol.get(0));
versch.mult(-1);
Vektor2D anfWin = new Vektor2D(this.pfeilPol.get(1));
anfWin.sub(this.pfeilPol.get(0));
double winkel = Math.atan(anfWin.x / anfWin.y);
Polygon2D p = (new PfeilMaster(this.pars)).segmentPfeilPol2D(
this.pfeilPol,
this.dicken,
PfeilMaster.EINFACHER_ABSCHLUSS,
this.anfang,
new Vektor2D(this.anfFakt, this.anfFakt),
new Vektor2D(1, 1));
p.verschiebe(versch);
p.skaliere(
Vektor2D.NULL_VEKTOR,
new Vektor2D(1 / this.dicken.get(0), 1 / this.dicken.get(0)));
p.drehe(Vektor2D.NULL_VEKTOR, winkel);
return p;
}
/**
* Erzeugt die zu zeichnenden Objekte, also die Teilsegmente des Pfeils
* Farbangaben, etc.
*
* @param skal Die Skalierung.
* @param versch Die Verschiebung.
*
* @return Die zu zeichnenden Objekte.
*/
public List<Object> erzeugeZeichenObjekte(
final double skal,
final Vektor2D versch) {
List<Object> liste = new ArrayList<Object>();
Pol2DMitAusgMerkm[] segs;
AusgMerkm ausg = new AusgMerkm(
Color.black,
Color.white,
true,
true);
this.loescheSegs();
this.addAllSegs(this.userSegs);
if (this.pfeilPol.size() > 1 && this.zeichneGrundPfeil) {
SegSpez segNeu = new SegSpez(
ausg,
0,
this.pfeilPol.size() - 1,
this.ende,
this.anfang,
new Vektor2D(this.anfFakt, this.anfFakt),
new Vektor2D(this.endFakt, this.endFakt));
this.addSeg(segNeu, false);
}
if (this.gestrichelt <= 0) {
segs = this.zeichenArt.erzeugePfeilsegmente(
this.pfeilPol,
this.dicken,
this.segBeschr,
this.pars);
} else {
segs = this.zeichenArt.gestrichelterPfeil(
this.pfeilPol,
this.dicken,
this.ende,
this.anfang,
new Vektor2D(this.anfFakt, this.anfFakt),
new Vektor2D(this.endFakt, this.endFakt),
this.gestricheltMerkm,
this.gestrichelt,
this.pars);
}
liste = Geometrie2D.erzeugeObjList(
segs,
skal,
versch);
return liste;
}
/**
* Zeichenmethode.
*
* @param g Das Grafikobjekt.
*/
public void paint(final Graphics g) {
long zeit = System.currentTimeMillis();
List<Object> liste = new LinkedList<Object>();
try {
liste = this.erzeugeZeichenObjekte(
this.skalierung,
this.verschiebung);
if (this.markiereEcken) {
AusgMerkm unmark1 = new AusgMerkm(
Color.black,
Color.white,
true,
true);
AusgMerkm unmark2 = new AusgMerkm(
Color.black,
Color.white,
false,
false);
AusgMerkm m1 = new AusgMerkm(
Color.black,
Color.red,
true,
true);
AusgMerkm m2 = new AusgMerkm(
Color.black,
Color.yellow,
true,
true);
ArrayList<Integer> markierung
= new ArrayList<Integer>(this.markierte.size());
for (int i : this.markierte) {
markierung.add(i);
}
this.zeichenArt.markiereEcken(
this.pfeilPol.toPol(
this.skalierung,
this.verschiebung),
liste,
markierung,
m2,
unmark1,
4);
markierung.clear();
markierung.add(this.mark1);
markierung.add(this.mark2);
this.zeichenArt.markiereEcken(
this.pfeilPol.toPol(
this.skalierung,
this.verschiebung),
liste,
markierung,
m1,
unmark2,
4);
}
if (this.ersteEcke != null && this.zweiteEcke != null) {
Polygon2D quad = new Polygon2D(4);
quad.add(new Vektor2D(this.ersteEcke));
quad.add(new Vektor2D(this.ersteEcke.x, this.zweiteEcke.y));
quad.add(new Vektor2D(this.zweiteEcke));
quad.add(new Vektor2D(this.zweiteEcke.x, this.ersteEcke.y));
liste.add(new AusgMerkm(
Color.lightGray,
Color.black,
true,
false));
liste.add(quad.toPol(this.skalierung, this.verschiebung));
}
LinkedList<AbstractMsg> msgsError
= this.pars.getMsgs(
(new MsgError(null, 0, null)).getType(),
zeit,
Long.MAX_VALUE);
LinkedList<AbstractMsg> msgsWarning
= this.pars.getMsgs(
(new MsgWarning(null, 0, null)).getType(),
zeit,
Long.MAX_VALUE);
if (this.fehlerStufe == 2 || !msgsError.isEmpty()) {
liste.addAll(this.ampel(2, new Vektor2D(50, 50), 7));
} else if (this.fehlerStufe == 1 || !msgsWarning.isEmpty()) {
liste.addAll(this.ampel(1, new Vektor2D(50, 50), 7));
} else {
liste.addAll(this.ampel(0, new Vektor2D(50, 50), 7));
}
liste.add(new AusgMerkm(
Color.black,
Color.red,
true,
true));
liste.addAll(this.fehlerQuellen(msgsError));
liste.addAll(this.fehlerQuellen(msgsWarning));
liste.add(new AusgMerkm(
Color.black,
Color.black,
true,
true,
"",
1,
20));
liste.add(new Integer(50 - 14));
liste.add(new Integer(130));
liste.add("" + this.pfeilPol.size());
liste.add(new Integer(50 + 20));
liste.add(new Integer(50));
liste.add(
""
+ Math.round(this.skalierung * 100)
+ " %");
Geometrie2D.maleObjListe(g, liste, this.pars);
this.elternMaster.setzeSegmentFarben(this.gestricheltMerkm);
} catch (final Exception e) {
liste.addAll(this.ampel(2, new Vektor2D(50, 50), 7));
Geometrie2D.maleObjListe(g, liste, this.pars);
SonstMeth.log(
SonstMeth.LOG_ERROR,
"Fehler beim Zeichnen des Pfeils: ",
this.pars);
SonstMeth.log(
SonstMeth.LOG_ERROR,
e.toString(),
this.pars,
"plain",
null);
throw new RuntimeException("Fehler beim Zeichnen des Pfeils");
}
}
/**
* Ersetzt den Teil zwischen den beiden markierten Punkten durch
* ein Beziersegment.
*
* @param bezKonst Die Bezierkonstante.
*/
public void bezier(final double bezKonst) {
double bezK = bezKonst;
Polygon2D bez;
Vektor2D v1, v2, v3, v4;
ArrayList<Integer> mark = new ArrayList<Integer>(4);
if (bezK > 1) {
bezK = fmg.fmg8.graphVis.zeichenModi.Konstanten.BEZ_NORMAL;
}
if (this.mark1 != null
&& this.mark2 != null
&& !this.mark1.equals(this.mark2)
&& this.markierte.size() == 4) {
mark.addAll(this.markierte);
Collections.sort(this.markierte, new IntComp());
v1 = this.pfeilPol.get(mark.get(0));
v2 = this.pfeilPol.get(mark.get(1));
v3 = this.pfeilPol.get(mark.get(2));
v4 = this.pfeilPol.get(mark.get(3));
bez = Geometrie2D.bezierKurve(v1, v2, v3, v4, bezK);
Polygon2D polNeu = new Polygon2D();
ArrayList<Double> dickenNeu = new ArrayList<Double>();
boolean platziert = false;
for (int i = 0; i < this.pfeilPol.size(); i++) {
if (!this.between(mark.get(0), mark.get(3), i)) {
polNeu.add(this.pfeilPol.get(i));
dickenNeu.add(this.dicken.get(i));
} else if (!platziert) {
for (int n = 0; n < bez.size(); n++) {
polNeu.add(bez.get(n));
dickenNeu.add(this.dicken.get(i));
}
platziert = true;
}
}
this.mark1 = null;
this.mark2 = null;
this.markierte.clear();
this.dicken = dickenNeu;
this.pfeilPol = polNeu;
} else if (this.markierte.size() > 4) {
LinkedList<Integer> marks = new LinkedList<Integer>();
for (int i = 0; i < markierte.size() - 4; i++) {
this.mark1 = markierte.get(i);
this.mark2 = markierte.get(i + 1);
marks.clear();
marks.addAll(this.markierte);
this.markierte.clear();
this.markierte.add(marks.get(i));
this.markierte.add(marks.get(i + 1));
this.markierte.add(marks.get(i + 2));
this.markierte.add(marks.get(i + 3));
this.bezier(bezKonst);
this.markierte.clear();
this.markierte.addAll(marks);
}
}
}
/**
* Ob der letzte Parameter zwischen dem ersten und dem zweiten Parameter
* liegt.
*
* @param z1 Die erste Grenzzahl.
* @param z2 Die zweite Grenzzahl.
* @param z Die zu testende Zahl.
*
* @return Ob die zu testende Zahl zwischen der ersten und zweiten
* Grenzzahl liegt.
*/
private boolean between(final double z1, final double z2, final double z) {
return (z >= z1 && z <= z2) || (z <= z1 && z >= z2);
}
/**
* F�gt eine Ausg-Spez hinzu.
*
* @param aktSeg Die Ausg-Spez.
*/
public void setzeAktSegAusg(final AusgMerkm aktSeg) {
int m1, m2;
Pfeilspitze polAnfang = this.anfang;
Pfeilspitze polEnde = this.ende;
if (this.mark1 == null || this.mark2 == null) {
return;
}
if (this.mark1 < this.mark2) {
m1 = this.mark1;
m2 = this.mark2;
} else if (this.mark1 > this.mark2) {
m1 = this.mark2;
m2 = this.mark1;
} else {
return;
}
if (m1 != 0) {
polEnde = PfeilMaster.EINFACHER_ABSCHLUSS;
}
if (m2 != this.pfeilPol.size() - 1) {
polAnfang = PfeilMaster.EINFACHER_ABSCHLUSS;
}
SegSpez neu = new SegSpez(
aktSeg,
m1,
m2,
polEnde,
polAnfang,
new Vektor2D(this.anfFakt, this.anfFakt),
new Vektor2D(this.endFakt, this.endFakt));
this.addSeg(neu, true);
this.userSegs.add(neu);
}
/**
* @return Returns the graphName.
*/
public String getGraphName() {
return this.robName;
}
/**
* Speichert die Darstellung des aktuellen Automaten in eine PNG-Datei.
*
* @param datNam Der Name der Datei (ohne Erweiterung).
* @param modus Der Modus (jpg, png, bmp, ...)
* @param skal Die Skalierung der Grafik.
*/
public void savePNG(
final String datNam,
final String modus,
final double skal) {
Geometrie2D.saveObjectsToFile(
this.erzeugeZeichenObjekte(skal, Vektor2D.NULL_VEKTOR),
datNam,
modus,
this.pars);
}
/**
* @return Returns the markiereEcken.
*/
public boolean isMarkiereEcken() {
return this.markiereEcken;
}
/**
* @param markEck The markiereEcken to set.
*/
public void setMarkiereEcken(final boolean markEck) {
this.markiereEcken = markEck;
}
/**
* @return Returns the aktDicke.
*/
public double getAktDicke() {
return this.aktDicke;
}
/**
* @param aktDick The aktDicke to set.
*/
public void setAktDicke(final double aktDick) {
int j = 0;
for (int i : this.markierte) {
this.dicken.set(i, aktDick);
j++;
}
if (j == 0) {
this.aktDicke = aktDick;
}
}
/**
* @return Returns the zeichneGrundPfeil.
*/
public boolean isZeichneGrundPfeil() {
return this.zeichneGrundPfeil;
}
/**
* @param grPfeil The zeichneGrundPfeil to set.
*/
public void setZeichneGrundPfeil(final boolean grPfeil) {
this.zeichneGrundPfeil = grPfeil;
}
/**
* @return Returns the markierte.
*/
public LinkedList<Integer> getMarkierte() {
return this.markierte;
}
/**
* Skaliert die Grafik auf Maximalgr��e relativ zum Zeichenfenster.
*/
public void skaliere() {
double xF = this.getWidth();
double yF = this.getHeight();
List<Object> objekte = this.erzeugeZeichenObjekte(
1,
Vektor2D.NULL_VEKTOR);
Vektor2D pLO
= new Vektor2D(Geometrie2D.rahmen(objekte).get(0));
Vektor2D pRU
= new Vektor2D(Geometrie2D.rahmen(objekte).get(1));
this.skalierung =
Math.min(xF / (pRU.x - pLO.x), yF / (pRU.y - pLO.y));
this.skalierung /= 1.2;
}
/**
* Zentriert zur Mitte des Fensters.
*/
public void zentriere() {
double xF = this.getWidth();
double yF = this.getHeight();
this.zentriere(new Vektor2D(xF / 2, yF / 2));
}
/**
* Zentriert die Grafik relativ zu einer angegebenen Mitte.
*
* @param mitte Das Zentrum.
*/
public void zentriere(final Vektor2D mitte) {
List<Object> objekte = this.erzeugeZeichenObjekte(
1,
Vektor2D.NULL_VEKTOR);
Vektor2D pLO = new Vektor2D(Geometrie2D.rahmen(objekte).get(0));
Vektor2D pRU = new Vektor2D(Geometrie2D.rahmen(objekte).get(1));
Vektor2D neuVersch = new Vektor2D(mitte);
Vektor2D zwisch = new Vektor2D(pLO);
zwisch.add(new Vektor2D((pRU.x - pLO.x) / 2, (pRU.y - pLO.y) / 2));
zwisch.mult(skalierung);
neuVersch.sub(zwisch);
this.verschiebung = neuVersch;
}
/**
* Wenn das Mausrad bewegt wurde.
*
* @param e Das zugeh�rige Event.
*/
@Override
public void mouseWheelMoved(final MouseWheelEvent e) {
final double konstSkal = 1.2;
final double maxZoom = 100;
final double minZoom = 0.01;
double xF = this.getWidth();
double yF = this.getHeight();
final Vektor2D mittVek = new Vektor2D(xF / 2, yF / 2);
final Vektor2D mouse = new Vektor2D(e.getPoint());
mouse.sub(mittVek); // TODO
if (e.getWheelRotation() > 0) {
this.skalierung /= konstSkal * Math.abs(e.getWheelRotation());
} else {
this.skalierung *= konstSkal * Math.abs(e.getWheelRotation());
}
if (this.skalierung > maxZoom) {
this.skalierung = maxZoom;
}
if (this.skalierung < minZoom) {
this.skalierung = minZoom;
}
this.zentriere(mittVek);
this.neuZeichnen();
}
/**
* @return Returns the anfang.
*/
public Pfeilspitze getAnfang() {
return this.anfang;
}
/**
* @return Returns the ende.
*/
public Pfeilspitze getEnde() {
return this.ende;
}
/**
* @param anf The anfang to set.
*/
public void setAnfang(final String anf) {
for (Pfeilspitze s : PfeilMaster.getSpitzen()) {
if (s.toString().equals(anf)) {
this.anfang = s;
}
}
}
/**
* @param end The ende to set.
*/
public void setEnde(final String end) {
for (Pfeilspitze s : PfeilMaster.getSpitzen()) {
if (s.toString().equals(end)) {
this.ende = s;
}
}
}
/**
* @param dick Setzt die Dicken.
*/
public void setDicken(final ArrayList<Double> dick) {
this.dicken = dick;
}
/**
* @return Die Dicken.
*/
public ArrayList<Double> getDicken() {
return this.dicken;
}
/**
* @return Returns the pfeilPol.
*/
public Polygon2D getPfeilPol() {
return this.pfeilPol;
}
/**
* @param aF The anfFakt to set.
*/
public void setAnfFakt(final double aF) {
this.anfFakt = aF;
}
/**
* @param eF The endFakt to set.
*/
public void setEndFakt(final double eF) {
this.endFakt = eF;
}
/**
* Gestrichelten Pfeil erzeugen.
*
* @param laenge Die L�nge der Strichelung
*/
public void gestrichelt(final double laenge) {
if (this.gestrichelt <= 0) {
this.gestrichelt = laenge;
} else {
this.gestrichelt = 0;
}
}
/**
* @return Returns the mark1.
*/
public Integer getMark1() {
return this.mark1;
}
/**
* @return Returns the mark2.
*/
public Integer getMark2() {
return this.mark2;
}
}