/************************************************************/ /* Kante.java Version 2003/03/28 */ /* */ /* Tom Fellmann, Christoph Weißenborn */ /* */ /************************************************************/ import java.awt.*; import java.io.*; import javax.swing.*; class Kante extends JComponent implements PN_Knoten { /***************************************************/ /* Daten-Teil */ /***************************************************/ public static final Color NORMAL_FARBE = Color.black; public static final Color TEXT_FARBE = Color.white; protected static int maxID=0; //globale Durchnummerierung aller Platz-Objekte, für ID private int ID; // private Point VonPkt; //Startpunkt private Point NachPkt; //Zielpunkt private String Text; //Beschriftung private Platz einPlatz; //Platz, je nach Typ vor- oder nach-Knoten private Transition eineTrans; //Transition, je nach Typ vor- oder nach-Knoten private Tupel wanderMarken; //beim Schalten zu bewegende Marken private static final int PLATZ_ZU_TRANSITION = 1; private static final int TRANSITION_ZU_PLATZ = 2; private int typ; private boolean seitletztemMalenGeaendert; private boolean alsMatrixDarstellen; /***************************************************/ /* Konstruktoren */ /***************************************************/ public Kante(String text, Platz vonPlatz, Transition nachTransition, Tupel fliessMarken){ this( text, vonPlatz, nachTransition, fliessMarken, PLATZ_ZU_TRANSITION); }//Kante-Konstruktor Platz -> Transition public Kante(String text, Transition vonTransition, Platz nachPlatz, Tupel fliessMarken){ this( text, vonTransition, nachPlatz, fliessMarken, TRANSITION_ZU_PLATZ); }//Kante-Konstruktor Transition -> Platz private Kante(String text, PN_Knoten von, PN_Knoten nach, Tupel fliessMarken, int typ){ this.ID = maxID; maxID++; this.typ = typ; if( typ==PLATZ_ZU_TRANSITION ){ this.einPlatz = (Platz)von; this.eineTrans = (Transition)nach; } else if( typ==TRANSITION_ZU_PLATZ ){ this.eineTrans = (Transition)von; this.einPlatz = (Platz)nach; } else throw new NullPointerException(); this.VonPkt = new Point(); this.NachPkt = new Point(); this.Text = new String( text); this.wanderMarken = new Tupel(fliessMarken); this.berechneEndpunkte(); Rectangle r = new Rectangle( VonPkt); r.add( NachPkt); this.setSize( r.getSize()); seitletztemMalenGeaendert = false; alsMatrixDarstellen = false; //this.setPreferredSize( getSize()); }//Kante-Konstruktor private Kante() { ID = -1; typ = 0; VonPkt = null; NachPkt = null; Text = null; einPlatz = null; eineTrans = null; wanderMarken = null; seitletztemMalenGeaendert = false; alsMatrixDarstellen = false; }//Konstruktor für Laden /***************************************************/ /* PN_Knoten-Implementierung */ /***************************************************/ public int getID() { return ID; }//getID public String getText() { return new String( Text); }//getText public boolean gleich(PN_Knoten Knoten) { return Knoten.getID() == ID; }//gleich public boolean isKlasse(String str) { return getClass().getName().compareTo(str)==0; }//isKlasse /***************************************************/ /* Darstellungsteil */ /***************************************************/ protected myJLabel[] getMatrixTexte() { myJLabel[] jls = new myJLabel[ Netz.getFarbanzahl()+ 1]; jls[0] = new myJLabel( Text); int h; for( int i=1; i 0 ) jls[i] = new myJLabel( Netz.Zweistellig( h), JLabel.LEFT); else jls[i] = new myJLabel( " ", JLabel.LEFT); return jls; }//getMatrixTexte protected int getBitMusterBenutzeFarben() { if( wanderMarken.getSummeAller() <= Netz.MAX_MARKENDARSTELLANZ ) return 0; int muster = 0; int FarbAnz = Netz.getFarbanzahl(); for( int i=0; i0 ) muster |= 1 << i; return muster; }//getBitMusterBenutzeFarben public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor( NORMAL_FARBE); g.drawLine( VonPkt.x, VonPkt.y, NachPkt.x, NachPkt.y); /*******************/ /* Pfeile zeichnen */ /*******************/ int dx = NachPkt.x - VonPkt.x; int dy = NachPkt.y - VonPkt.y; double laenge = Math.sqrt( dx*dx+dy*dy); int hdx = (int)((13*dx)/laenge); int hdy = (int)((13*dy)/laenge); g.drawLine( NachPkt.x, NachPkt.y, NachPkt.x-hdx+hdy, NachPkt.y-hdy-hdx); g.drawLine( NachPkt.x, NachPkt.y, NachPkt.x-hdx-hdy, NachPkt.y-hdy+hdx); /**************/ /*Beschriftung*/ /**************/ Point p = getMittelPkt(); g.setColor( TEXT_FARBE); g.drawString( Text, p.x, p.y-2 ); if( wanderMarken.getSummeAller()==0 ){ g.drawString( "leer", p.x-8, p.y+12); } else if( alsMatrixDarstellen ){ g.drawString( "in Matrix", p.x-20, p.y+12); if( seitletztemMalenGeaendert ){ Petri.frame.gefNetz.setMatrixKanteGeaendert(); } } else { int benuFarbAnz = 0, FarbAnz = Netz.getFarbanzahl(), breite = Netz.KANTE_MARKEN_GROESSE, benutzt[] = new int[FarbAnz]; for( int i=0; i0 ){ benutzt[benuFarbAnz] = i; benuFarbAnz++; } p.translate( -((breite+1)*benuFarbAnz>>1)+2, 2); for( int i=0; i= maxID) maxID = neuKante.ID+1; if( !Netz.IntLesenBisCharOK( 1, 'k', LD)) break KanteLesen; if( !Netz.IntLesenBisCharOK( 2, 'k', LD)) break KanteLesen; neuKante.VonPkt = new Point( LD.wert[1], LD.wert[2]); if( !Netz.IntLesenBisCharOK( 1, 'k', LD)) break KanteLesen; if( !Netz.IntLesenBisCharOK( 2, 'k', LD)) break KanteLesen; neuKante.NachPkt = new Point( LD.wert[1], LD.wert[2]); if( !Netz.IntLesenBisCharOK( 1, 'k', LD)) break KanteLesen; if( !Netz.TextLesenOK( LD.wert[1], LD)) break KanteLesen; neuKante.Text = LD.text; if( !Netz.IntLesenBisCharOK( 1, 'k', LD)) break KanteLesen; neuKante.typ = LD.wert[1]; if( !Netz.IntLesenBisCharOK( 1, 'k', LD)) break KanteLesen; if( !Netz.IntLesenBisCharOK( 2, 'k', LD)) break KanteLesen; if( (neuKante.typ == PLATZ_ZU_TRANSITION ) && Ps.IDvorhanden(LD.wert[1]) && Ts.IDvorhanden(LD.wert[2])) { (neuKante.einPlatz = Ps.GetPlatzMitID(LD.wert[1])).WegKanteEinfuegen(neuKante); (neuKante.eineTrans = Ts.GetTransitionMitID(LD.wert[2])).VorKanteEinfuegen(neuKante); } else if( (neuKante.typ == TRANSITION_ZU_PLATZ ) && Ts.IDvorhanden(LD.wert[1]) && Ps.IDvorhanden(LD.wert[2])) { (neuKante.eineTrans = Ts.GetTransitionMitID(LD.wert[1])).NachKanteEinfuegen(neuKante); (neuKante.einPlatz = Ps.GetPlatzMitID(LD.wert[2])).HinKanteEinfuegen(neuKante); } else break KanteLesen; eTupel = Tupel.Laden( LD); if( eTupel == null) break KanteLesen; neuKante.MarkenZuweisen( eTupel); if( !Netz.EinlesenOK( LD)) break KanteLesen; neuKante.seitletztemMalenGeaendert = true; return neuKante; } return null; } catch(Exception e) { return null; } }//Laden /***************************************************/ /* strukturelle Aenderungen */ /***************************************************/ public void Leeren() { if( alsMatrixDarstellen ){ Petri.frame.gefNetz.InMatrixEinfuegen( this, false); alsMatrixDarstellen = false; seitletztemMalenGeaendert = true; } }//Leeren public Point getVonPkt() { return new Point(VonPkt); }//getVonPkt public Point getNachPkt() { return new Point(NachPkt); }//getNachPkt public Point getMittelPkt() { return new Point( (VonPkt.x+NachPkt.x)>>1, (VonPkt.y+NachPkt.y)>>1); }//getNachPkt /***************************************************/ /* Darstellungsteil */ /***************************************************/ private int sign(int a) { if( a > 0 ) return 1; else if( a < 0 ) return -1; else return 0; }//sign protected void berechneEndpunkte() { Point vPkt = getVonKnoten().getMittelPkt(); Point nPkt = getNachKnoten().getMittelPkt(); int dx = nPkt.x - vPkt.x; int dy = nPkt.y - vPkt.y; double laenge = Math.sqrt( dx*dx+dy*dy); int radius = einPlatz.getRadius(); Dimension groesse = eineTrans.getGroesse(); if( typ==PLATZ_ZU_TRANSITION ){ if( Math.abs(dy) > Math.abs(dx)) { //stärker nach oben oder unten NachPkt.y = nPkt.y-sign(dy)*(groesse.height>>1); if( dy != 0) NachPkt.x = nPkt.x-(dx*groesse.width)/(Math.abs(dy)<<1); else NachPkt.x = nPkt.x- (groesse.width>>1); } else { NachPkt.x = nPkt.x-sign(dx)*(groesse.width>>1); if( dx != 0) NachPkt.y = nPkt.y-(dy*groesse.height)/(Math.abs(dx)<<1); else NachPkt.y = nPkt.y- (groesse.height>>1); } VonPkt.x = vPkt.x + (int)(dx*radius/laenge); VonPkt.y = vPkt.y + (int)(dy*radius/laenge); } else if( typ==TRANSITION_ZU_PLATZ ){ if( Math.abs(dy) > Math.abs(dx)) { VonPkt.y = vPkt.y+sign(dy)*(groesse.height>>1); if( dy != 0) VonPkt.x = vPkt.x+(dx*groesse.width)/(Math.abs(dy)<<1); else VonPkt.x = vPkt.x+ (groesse.width>>1); } else { VonPkt.x = vPkt.x+sign(dx)*(groesse.width>>1); if( dx != 0) VonPkt.y = vPkt.y+(dy*groesse.height)/(Math.abs(dx)<<1); else VonPkt.y = vPkt.y- (groesse.height>>1); } NachPkt.x = nPkt.x - (int)(dx*radius/laenge); NachPkt.y = nPkt.y - (int)(dy*radius/laenge); } }//berechnePunkte public void PositionAktualisieren() { berechneEndpunkte(); }//PositionAktualisieren public void TextAendern(String neuerText) { Text = neuerText; seitletztemMalenGeaendert = true; }//TextAendern /***************************************************/ /* Algorithmen-Teil */ /***************************************************/ public Tupel getKopieMarkenFluss() { return wanderMarken; }//getMarkenFluss private static boolean bestimmeAlsMatrixDarstellen(Tupel testMarken){ Tupel maxMark = new Tupel( Netz.MAX_MARKENDARSTELLANZ); int FarbAnz = Netz.getFarbanzahl(), maxFarb = Netz.MAX_FARBENDARSTELLANZ, benuFarb = 0; for( int i=0; i0 ) benuFarb++; return !maxMark.ArgumentKleinerGleich( testMarken) || (benuFarb>maxFarb); }//bestimmeAlsMatrixDarstellen public boolean MarkenZuweisen(Tupel neueMarken) { if( wanderMarken==null ){ //beim Laden? wanderMarken = neueMarken; if( bestimmeAlsMatrixDarstellen( neueMarken) ){ Petri.frame.gefNetz.InMatrixEinfuegen( this, true); alsMatrixDarstellen = true; } seitletztemMalenGeaendert = true; return true; } else if( !wanderMarken.wertGleich( neueMarken) ){ boolean neu = bestimmeAlsMatrixDarstellen( neueMarken); if( wanderMarken.Zuweisen( neueMarken) ){ if( neu && !alsMatrixDarstellen ){ Petri.frame.gefNetz.InMatrixEinfuegen( this, true); alsMatrixDarstellen = true; } else if( !neu && alsMatrixDarstellen ){ Petri.frame.gefNetz.InMatrixEinfuegen( this, false); alsMatrixDarstellen = false; } seitletztemMalenGeaendert = true; return true; } else { if( alsMatrixDarstellen ){ Petri.frame.gefNetz.InMatrixEinfuegen( this, false); alsMatrixDarstellen = false; } seitletztemMalenGeaendert = true; return false; } } else return true; }//MarkenAendern /***************************************************/ /* ...-Teil */ /***************************************************/ }//Kante-Klasse