/*
* YAV (Yet another Visualiser)
* (c) 2004 by Robin Quast
* Version 1.0 (04.03.2004)
*
* erstellt im Rahmen der Diplomarbeit
* "Theorie und Java- Realisierung
* ausgewählter Algorithmen zur
* Bestimmung kürzester Wege in Graphen"
*
* betreut durch Prof. Dr. Lenze
* an der Fachhochschule Dortmund
* im SS 2003/ WS 2003/2004
*
* @(#)Graph.java 1.6 04/03/09
*/
/* To Do:
* - Beim Zeichnen der Pfeile die Steigung an dem Zielknoten ermitteln??
* - Kante mit Gegenkante kann nicht per Direktklick gelöscht werden => Routine
* wird deaktiviert.
*/
import javax.swing.*;
import java.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import java.util.Enumeration;
import java.lang.Math;
import java.util.Collections;
import java.awt.geom.*;
import java.awt.print.PrinterJob;
import java.awt.print.*;
import javax.swing.event.*;
import java.io.*;
/** Klasse die die Graphenerstellung und die Anzeige übernimmt. Die Druckausgabe
* besitzt zur Zeit nur eingeschänkte Funktionalität und wird in einer kommenden
* Version erweitert.
*/
public class Graph
extends JPanel
implements Printable, MouseListener, MouseMotionListener, TableModelListener {
Graphics2D g2d=null;
GraphNodeList graphDaten = new GraphNodeList();
GraphNode selectedNode = null;//new GraphNode(null,null);
GraphEdgeList graphKanten = new GraphEdgeList();
EdgeTable etable = null;
EdgeTableModel etmodel = null;
JPanel eastpanel = new JPanel();
Adjazenzliste adlist = null;
int drawMode=1;
int radius=20;
int nodeCounter = 0;
Vector geloeschteKnoten = null;
Color selectionsFarbe = Color.blue;
Color linienFarbe = Color.blue;
Color schriftFarbe = Color.black;
int selectedInt = -1;
boolean dragged=false;
int nodeLimit = 100; // nicht mehr als 100 Knoten (0...99) sind zugelassen
// ist aber nur ein Darstellungsproblem bzgl. des Textes in dem Knoten und sollte hier ausreichen
// nodeLimit darf NICHT den Wert Integer.MAX_VALUE erhalten.
Rectangle area = null;
JLabel ueberschrift = new JLabel();
/** Konstruktor.
*/
public Graph() {
setLayout(new BorderLayout());
etmodel = new EdgeTableModel();
etable= new EdgeTable(etmodel);
etmodel.addTableModelListener(this);
JScrollPane scrollPane = new JScrollPane(etable);
eastpanel.setLayout(new BoxLayout(eastpanel,BoxLayout.Y_AXIS));
ueberschrift.setAlignmentX(Component.CENTER_ALIGNMENT);
ueberschrift.setText("Kantenliste");
eastpanel.add(ueberschrift);
scrollPane.setAlignmentX(Component.CENTER_ALIGNMENT);
eastpanel.add(scrollPane);
//add(eastpanel,BorderLayout.EAST);
setBackground(Color.white);
addMouseMotionListener(this);
addMouseListener(this);
adlist = new Adjazenzliste();
geloeschteKnoten=new Vector();
graphDaten=new GraphNodeList();
setSize(new Dimension(790,590));
}
/** Zurückgeben des Panels, das die Knotentabelle enthält.
*/
public JPanel getViewPanel() {
return eastpanel;
}
/** Den Splitpane zurückgeben.
*/
public JSplitPane getSplitPane() {
JSplitPane spp_graph = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this, getViewPanel());
spp_graph.setContinuousLayout(true);
spp_graph.setOneTouchExpandable(true);
spp_graph.setDividerLocation(600);
return spp_graph;
}
/** Werden die Kosten für eine Kante eingegeben, dann muss der
* Graph neu gezeichnet werden.
*/
public void tableChanged(TableModelEvent e) {
repaint();
}
/** Den Zeichenmodus setzen.
*/
public void setDrawMode(int mode) {
drawMode=mode;
}
/** Eventroutine bei einem Mausdrag. Dabei wird der Knoten bewegt, der
* selektiert ist und sich unter dem Mauszeiger befindet. Befindet sich kein
* Knoten unter dem Mauszeiger, oder ist kein Knoten selektiert,
* dann wird nichts gemacht.
*/
public void mouseDragged(MouseEvent e) {
e.consume();
if (selectedNode!=null) {
dragged=true;
selectedNode.rectangle=new Rectangle(e.getX()-radius/2,e.getY()-radius/2,radius,radius);
repaint();
}
}
/** Event für die Mausbewegung.
*/
public void mouseMoved(MouseEvent e) {
}
/** Drücken der Maus löst je nach Modus eine bestimmte Reaktion aus.
*/
public void mousePressed(MouseEvent e) {
e.consume();
Rectangle nr = new Rectangle(e.getX()-radius/2,e.getY()-radius/2,radius,radius);
GraphNode intersectsNode=graphDaten.intersectsWith(nr);
if (intersectsNode!=null) {
switch (drawMode) {
case 1: // Knoten zeichnen
selectedNode=intersectsNode;
selectedInt=selectedNode.value;
selectedNode.setColor(selectionsFarbe);
break;
case 2: // Knoten löschen
selectedNode=intersectsNode;
geloeschteKnoten.add(selectedNode.getNode());
graphDaten.remove(selectedNode);
adlist.remove(selectedNode.getNode());
removeRows(selectedNode.getNode());
selectedNode=null;selectedInt=-1;
break;
case 3: // Zeichenmodus Kante
if (selectedNode==null) {
selectedNode=intersectsNode;
selectedInt=selectedNode.getValue();
selectedNode.setColor(selectionsFarbe);
} else {
Edge tmp_edge=new Edge(selectedNode.getNode(),intersectsNode.getNode(),0);
adlist.add(tmp_edge);
//adlist.add(selectedNode.node,intersectsNode.node,0);
selectedNode=null;selectedInt=-1;
etmodel.addRow(tmp_edge);
}
break;
case 4: // Kante löschen
// Routine um die Kanten per Knotenklick zu löschen
if (selectedNode==null) {
selectedNode=intersectsNode;
selectedInt=selectedNode.getValue();
selectedNode.setColor(selectionsFarbe);
} else {
int tmp_kosten=adlist.getCost(selectedNode.getNode(),intersectsNode.getNode());
Edge tmp_edge=new Edge(selectedNode.getNode(),intersectsNode.getNode(),tmp_kosten);
adlist.remove(tmp_edge);
//adlist.add(selectedNode.node,intersectsNode.node,0);
selectedNode=null;selectedInt=-1;
removeRow(tmp_edge);
}
break;
}
} else {
if (drawMode==4) {
Point punkt = new Point(e.getX(),e.getY());
//removeRow(punkt); // mit Kanten- Direktklick, diese löschen funktioniert noch nicht sauber für Kanten mit Gegenkanten, also als QuadCurve gemalte Kanten
}
selectedNode=null;selectedInt=-1;
}
dragged=false;
repaint();
}
/** Loslassen der Maustaste löst je nach Zeichenmodus eine spezielle
* Reaktion aus.
*/
public void mouseReleased(MouseEvent e) {
e.consume();
int x=e.getX();int y=e.getY();
switch(drawMode) {
case 1:
if (nodeCounter<nodeLimit) {
Rectangle nr = new Rectangle(e.getX()-radius/2,e.getY()-radius/2,radius,radius);
GraphNode intersects_node = graphDaten.intersectsWith(nr);
if (intersects_node==null) {
int node_number=getNextNodeNumber();
adlist.add(node_number);
graphDaten.add(new GraphNode(node_number,nr));
selectedInt=-1;
// wenn der Knoten noch nicht in die Liste aufgenommen wurde
} else {
if (selectedNode==null) {
selectedNode=intersects_node;
selectedInt=selectedNode.getValue();
selectedNode.setColor(selectionsFarbe);
} else {
selectedNode=null;
selectedInt=-1;
}
}
}
break;
case 2:
break;
}
dragged=false;
repaint();
}
/** Für die Knotenerzeugung eine neue Knotennummer holen. Dabei
* werden gelöschte Knotennummern berücksichtigt.
*/
public int getNextNodeNumber() {
if (geloeschteKnoten.size()!=0){
Collections.sort(geloeschteKnoten);
Node min_node=(Node)geloeschteKnoten.firstElement();
if (Math.min(min_node.value,nodeCounter)==nodeCounter) {
nodeCounter++;
} else {
geloeschteKnoten.remove(min_node);
}
return Math.min(min_node.value,nodeCounter);
} else return nodeCounter++;
}
/** Mausevent für das Bewegen der Maus in einem Bereich.
*/
public void mouseEntered(MouseEvent e) {
}
/** Mausevent für das Verlassen der Maus aus einem Bereich.
*/
public void mouseExited(MouseEvent e) {
}
/** Mausevent für das Klicken der Maus.
*/
public void mouseClicked(MouseEvent e) {
}
/** Zeichnen der Komponenten. Z.B. Kanten, Knoten usw.
*/
public void paintComponent(Graphics g) {
// male Knoten aus Vector und selektierten Knoten
super.paintComponent(g);
g2d=(Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
//erzeuge das Rechteck, welches zur überprüfung dient, ob ein Rechteck innerhalb
// des Malbereichs liegt
Dimension dim = getSize();
int w = (int)dim.getWidth();
int h = (int)dim.getHeight();
area = new Rectangle(dim);
paintEdges(g2d);
paintNodes(g2d);
}
/** Zeichnen der Knoten (auch für Druckerausgabe)
*/
void paintNodes(Graphics2D g2d) {
// male die Knoten
int anzahl_knoten = graphDaten.getLength();
for (int i=0; i<anzahl_knoten;i++) {
GraphNode tmp_gn = graphDaten.get(i);
if (tmp_gn!=null) {
if (tmp_gn!=selectedNode) {
paintGraphNode(tmp_gn,g2d,false);
} else {
paintGraphNode(tmp_gn,g2d,true);
}
}
}
}
/** Zeichnen der Kanten (auch für Druckerausgabe)
*/
void paintEdges(Graphics2D g2d){
graphKanten.removeAllElements();
// male die Kanten
int highestNodeNumber=adlist.getMaxNodeNumber();
for (int i=0; i<=highestNodeNumber;i++) {
// wenn es Kanten gibt, dann durchlaufe die Kantenmenge
// und male die Kanten
Vector edges=adlist.getEdgesWithTail(i);
if (edges!=null) {
Enumeration tmp_enum = edges.elements();
while (tmp_enum.hasMoreElements()) { // solange noch Knoten in der Liste gefunden werden, die gezeiochnet werden müssen
Edge tmp_kante = (Edge) tmp_enum.nextElement(); // Hole Element aus Vector
paintEdge(tmp_kante,g2d);
}
}
}
}
/** Malt eine Kante, die interaktiv oder per GraphNodeList und Adjazenzliste
* vorgegeben ist.
*/
void paintEdge(Edge tmp_kante,Graphics2D g2d) {
// Mittelpunkt zu Head und Tail holen
Point head = graphDaten.getMidpoint(tmp_kante.getHeadValue());
Point tail = graphDaten.getMidpoint(tmp_kante.getTailValue());
// prüfen, ob die Kante eine Gegenkante enthält
boolean enthaelt_gegenkante=adlist.contains(new Edge(tmp_kante.getHead(),tmp_kante.getTail()));
// Koordinaten der Kosten festhalten
Point cost_position=new Point();
cost_position.setLocation((2*head.x+tail.x)/3,(2*head.y+tail.y)/3);
// male den Pfeil
// berechne den Drehwinkel
double y21=(-(head.getY()-tail.getY()));
double x21=(head.getX()-tail.getX());
double yx21 = 0;
double drehung = 0;
if (x21==0) {
yx21 = (2/3);
drehung=Math.PI*1/4;
if (y21>=0) {
drehung=Math.PI*5/4;
}
} else {
if (y21==0) {
yx21=0;
} else {
yx21 = y21/x21;
}
drehung = Math.PI*3/4-Math.atan( yx21 );
}
double k=0;
if (enthaelt_gegenkante) k=0.3;
int[] x=new int[3];
int[] y=new int[3];
int vorzeichen=1;
if (x21<=0) vorzeichen=(-1);
// berechne die Polygonpunkte, die den Pfeil darstellen
x[0]=head.x;x[1]=head.x+20*vorzeichen;x[2]=head.x+10*vorzeichen;
y[0]=head.y;y[1]=head.y+10*vorzeichen;y[2]=head.y+20*vorzeichen;
// erzeuge das Polygon
Polygon pfeil = new Polygon(x,y,3);
if (tmp_kante.getHeadValue()==tmp_kante.getTailValue()) drehung=Math.PI*2/7; // Koordinatensystem drehen
g2d.rotate( drehung+k,head.x,head.y); // Koordinatensystem drehen
g2d.setColor(linienFarbe); // Liniesnfarbe setzen
g2d.fillPolygon(pfeil); // Polygon malen/ rendern
g2d.rotate( -drehung-k,head.x,head.y); // Koordinatensystem zurückdrehen
g2d.setColor(schriftFarbe); // "normale" Farbe setzen
// Kosteninformationen rendern
//g2d.drawString(""+tmp_kante.getCost(),cost_position.x,cost_position.y);
// male die Kante mit der Drehung, die für den Pfeil berechnet wurde.
if (enthaelt_gegenkante || tmp_kante.getHeadValue()==tmp_kante.getTailValue()) {
int korrektur=0;
if (head.x>tail.x) {
korrektur=1;
} else {
korrektur=-1;
}
// mittelpunkt der Kurve berechnen
//Point mid = new Point((head.x+tail.x)/2+30*korrektur,(head.y+tail.y)/2+30*korrektur);
if (tmp_kante.getHeadValue()==tmp_kante.getTailValue()) { // schlinge malen
CubicCurve2D.Double linie = new CubicCurve2D.Double(tail.getX(),tail.getY(), head.getX()-40,head.getY()-60,head.getX()+40,head.getY()-60,head.getX(),head.getY());
graphKanten.add(tmp_kante,(Object)linie);
cost_position.setLocation(head.x,head.y-50);
g2d.setColor(linienFarbe);
g2d.draw(linie);
} else { // kante mit gegenkante muss gebogen dargestellt werden
// initialisiere entsprechende Variablen
Point max,min;
Point mitte = new Point();
vorzeichen=1; // head ist kleiner als tail
// Wenn x für head und tail gleich sind, dann liegen die Punkte
// waagerecht zueinander => einfachere Punktberechnung
if (head.getX()==tail.getX()) {
if (head.getY()<tail.getY()) {
min=head;
max=tail;
} else {
max=head;
min=tail;
vorzeichen=-1;
}
// Mitte der beiden Punkte berechnen
mitte.setLocation(max.getX()+40*vorzeichen,min.getY()+((max.getY()-min.getY())/2));
QuadCurve2D.Double linie = new QuadCurve2D.Double(tail.getX(),tail.getY(), mitte.getX(),mitte.getY(),head.getX(),head.getY());
graphKanten.add(tmp_kante,(Object)linie);
g2d.setColor(linienFarbe);
g2d.draw(linie);
g2d.setColor(schriftFarbe);
cost_position.setLocation(mitte.getX(),mitte.getY());
g2d.drawString(""+tmp_kante.getCost(),cost_position.x,cost_position.y);
}
// Wenn y für head und tail gleich sind, dann
// liegen beide Punkte sekrecht zureinander
// => einfachere Punktberechnung, kein Drehen nötig
if (head.getY()==tail.getY()) {
if (head.getX()<tail.getX()) {
min=head;
max=tail;
} else {
max=head;
min=tail;
vorzeichen=-1;
}
mitte.setLocation(min.getX()+((max.getX()-min.getX())/2),max.getY()+40*vorzeichen);
QuadCurve2D.Double linie = new QuadCurve2D.Double(tail.getX(),tail.getY(), mitte.getX(),mitte.getY(),head.getX(),head.getY());
graphKanten.add(tmp_kante,(Object)linie);
g2d.setColor(linienFarbe);
g2d.draw(linie);
g2d.setColor(schriftFarbe);
cost_position.setLocation(mitte.getX(),mitte.getY());
g2d.drawString(""+tmp_kante.getCost(),cost_position.x,cost_position.y);
}
if ((head.getY()!=tail.getY()) && (head.getX()!=tail.getX())) {
// hilfspunkt, der den waagerechten Tail Punkt darstellt
Point hilfetail = new Point();
// berechne die Streckenlänge nach Pytogoras
double streckenlaenge = Math.sqrt(Math.pow(Math.abs(head.getX()-tail.getX()),2)+Math.pow(Math.abs(head.getY()-tail.getY()),2));
// setze den Mittelpunkt der zu zeichnenden Waagerechten Strecke
mitte.setLocation(head.getX()+streckenlaenge/2*vorzeichen,head.getY()+40*vorzeichen);
// Setze den Endpunkt der Waagerechten Strecke
hilfetail.setLocation(head.getX()+streckenlaenge*vorzeichen,head.getY());
g2d.setColor(linienFarbe);
if (head.getY()<tail.getY()) g2d.setColor(schriftFarbe);
//g2d.rotate( -(drehung+Math.PI*5/4),head.x,head.y); // Koordinatensystem zurückdrehen
double kor;
if (head.getX()<tail.getX()) kor=Math.PI*5/4;
else kor=Math.PI*1/4;
g2d.rotate( drehung+kor,head.x,head.y); // Koordinatensystem drehen
// render die Kosteninformationen der Kante
cost_position.setLocation(mitte.x,mitte.y);
g2d.setColor(schriftFarbe);
g2d.drawString(""+tmp_kante.getCost(),cost_position.x,cost_position.y);
QuadCurve2D.Double linie = new QuadCurve2D.Double(hilfetail.getX(),hilfetail.getY(), mitte.getX(),mitte.getY(),head.getX(),head.getY());
g2d.setColor(linienFarbe);
//AffineTransform at=g2d.getTransform();
graphKanten.add(tmp_kante,(Object)linie);
g2d.draw(linie);
g2d.rotate( -(drehung+kor),head.x,head.y); // Koordinatensystem zurückdrehen
}
}
} else {
Line2D.Double linie = new Line2D.Double(tail, head);
graphKanten.add(tmp_kante,(Object)linie);
// Für die Verwaltung in GraphEdgeList wird hier eine QuaDCurve verwendet
//QuadCurve2D.Double linie=new QuadCurve2D.Double(tail.getX(),tail.getY(), head.getX(),head.getY(),head.getX(),head.getY());
g2d.setColor(linienFarbe);
g2d.draw(linie);
g2d.setColor(schriftFarbe);
g2d.drawString(""+tmp_kante.getCost(),cost_position.x,cost_position.y);
}
g2d.setColor(schriftFarbe);
}
/** Malt einen Knoten.
*/
void paintGraphNode(GraphNode gn,Graphics2D g2d,boolean filled) {
Rectangle tmp_rec =new Rectangle();
tmp_rec = gn.rectangle;
boolean ok = true;//checkRect(tmp_rec);
if (ok) { // falls Zeichnen möglich
g2d.setColor(Color.white);
g2d.fillArc(tmp_rec.x, tmp_rec.y, tmp_rec.width , tmp_rec.height , 0, 360);
if (filled) {
g2d.setColor(gn.getColor());
g2d.fillArc(tmp_rec.x, tmp_rec.y, tmp_rec.width , tmp_rec.height , 0, 360);
} else {
g2d.setColor(selectionsFarbe);
g2d.drawArc(tmp_rec.x , tmp_rec.y, tmp_rec.width , tmp_rec.height , 0, 360);
}
// male Knotentext
g2d.setColor(Color.black);
int x_korrektur=3;
if (gn.getValue()>9) x_korrektur=6;
g2d.drawString(""+gn.getValue(),tmp_rec.x+radius/2-x_korrektur,tmp_rec.y+radius/2+5);
}
}
/** Prüft, ob das Rechteck rect in der "area" liegt. "area" stellt die
* Zeichenfläche dar. Liegt das Rechteck innerhalb der Fläche, so wird
* true zuückgegeben. liegt es ausserhalb der Fläche, dann ist der
* Rückgabewert false.
*/
boolean checkRect(Rectangle rect){
// ist keine Zeichenfläche definiert, dann
// false zurückgeben
if (area == null) {
return false;
}
// liegt das Rechteck rect innerhalb der area, dann
// true zurückgeben
if(area.contains(rect.x, rect.y, radius, radius)){
return true;
}
// nochfolgender Code wird nur ausgeführt, wenn das Rechteck NICHT
// in der area enthalten ist
// hole die Koordinaten des Rechtecks in "temopräre" Variablen
int new_x = rect.x;
int new_y = rect.y;
// teste rechte Seite
if((rect.x+radius)>area.getWidth()){
new_x = (int)area.getWidth()-radius;
}
// teste linke Seite
if(rect.x < 0){
new_x = 0;
}
// teste untere Seite
if((rect.y+radius)>area.getHeight()){
new_y = (int)area.getHeight()-radius;
}
// teste obere Kante
if(rect.y < 0){
new_y = 0;
}
// setze neue Koordinaten für das Rechteck
rect.setLocation(new_x, new_y);
return false;
}
/** Löscht eine Kantenzeile aus der Tabelle.
*/
public void removeRow(Point p) {
// Kanten per Direktklick löschen
Edge kante = graphKanten.removeIntersectsEdge(p);
if (kante!=null) {
removeRow(kante);
adlist.remove(kante);
}
}
/** Löscht eine Kantenzeile mti dem Index <I>index</I> aus der Tabelle.
*/
public void removeRow(int index) {
if (index>=0) {
Integer t=(Integer)etable.getValueAt(index,0);
Integer h=(Integer)etable.getValueAt(index,1);
Integer c=(Integer)etable.getValueAt(index,2);
Edge kante = new Edge (t.intValue(),h.intValue(),c.intValue());
etable.removeRow(index);
adlist.remove(kante);
YAV.status.setText("Kante "+kante+" wurde gelöscht.");
} else YAV.status.setText("Sie haben keine Kante in der Kantenliste selektiert.");
repaint();
}
/** Löscht zu einem Knoten alle Kanten in der Kantentabelle.
*/
public void removeRows(Node knoten) {
int zeilenanzahl=etmodel.getRowCount();
int i=0;
while (i<zeilenanzahl) {
int tailint=((Integer)etmodel.getValueAt(i, 0)).intValue();
int headint=((Integer)etmodel.getValueAt(i, 1)).intValue();
if ((knoten.getValue()==tailint) || (knoten.getValue()==headint)) {
removeRow(i);
} else {
i++;
}
zeilenanzahl=etmodel.getRowCount();
}
repaint();
}
/** Löscht die übergebene Kante aus der Tabelle.
*/
public void removeRow(Edge kante) {
int index=etmodel.indexOf(kante);
if (index!=-1) removeRow(index);
//repaint();
}
/** Druckroutine, benötigt Java 1.4.2.
*/
public int print(Graphics g, PageFormat pf, int pi) throws PrinterException
{
if (pi > 1) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2d=(Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
//erzeuge das Rechteck, welches zur überprüfung dient, ob ein Rechteck innerhalb
// des Malbereichs liegt
// image
Dimension dim = getSize();
area = new Rectangle(dim);
double scale =Math.min(pf.getImageableWidth()/getWidth(),pf.getImageableHeight()/getHeight());
scale=Math.min(1.0,scale);
g2d.translate(pf.getImageableX(), pf.getImageableY());
g2d.scale(scale, scale);
switch (pi) {
case 0: YAV.status.setText("Seite 1 wird gedruckt...");
paintEdges(g2d);
paintNodes(g2d);
break;
case 1: YAV.status.setText("Seite 2 wird gedruckt...");
printNodeList(g2d,pf);
break;
}
return Printable.PAGE_EXISTS;
}
/** Drucken der Knotenliste.
*/
public void printNodeList(Graphics2D g2d,PageFormat pf) {
// auf einer neuen Seite sollte hier die Knotenliste gedruckt werden
int start=(int)area.y+(int)area.height;
//g2d.drawString("Kantenliste",(int)pf.getImageableX(),(int)pf.getImageableX());
ueberschrift.print(g2d);
etable.print(g2d);
}
/** Speichern der Daten in zwei Dateien. Eine Datei mit Endung .ygd für
* die GraphKnotenListe und eine für die Adjazenzliste mit Endung .yal.
*/
public void writeGraphDatenToFile(String datei) {
graphDaten.writeTo(datei+".ygd");
adlist.writeTo(datei+".yal");
}
/** Lesen der Daten aus den Dateien mit den Endungen .ygd und .yal.
*/
public void readGraphDatenFromFile(String datei) {
init();
graphDaten.readFrom(datei+".ygd");
adlist.readFrom(datei+".yal");
nodeCounter=adlist.getMaxNodeNumber()+1;
etmodel.initialiseTable(adlist);
erzeugeGeloeschteKnotenVector();
repaint();
}
/** Knotenvektor für das merken der gelöschten Knoten, also den
* Lücken in der Knotenliste erzeugen.
*/
private void erzeugeGeloeschteKnotenVector() {
geloeschteKnoten = new Vector();
for (int i=0;i<=adlist.getMaxNodeNumber();i++) {
Vector nlist=adlist.getEdgesWithTail(i);
if (nlist==null) {
geloeschteKnoten.add(new Node(i));
}
}
}
/** Initialisierung.
*/
public void init() {
adlist = new Adjazenzliste();
geloeschteKnoten=new Vector();
graphDaten=new GraphNodeList();
etmodel.removeRows();
selectedNode=null;selectedInt=-1;
nodeCounter=0;
repaint();
}
}
|