/**
   Klasse Draw<BR>  <BR>
   Sprache:  JAVA<BR>
   Autor:    Fabian Wleklinski, Martin Klossek, Martin Meedt<BR>
   Datum:    23.05.1999<BR>
   Funktion: Hauptklasse des JavaMalprogramms

   <BR>&nbsp;<BR>

   Klasse ist Zeichenbrett und Steuerzentrale des einfachen JavaMalprogramms
*/

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.image.*;

/** Klasse Draw: Zeichenbrett und Steuerzentrale */
public class Draw extends Applet { // implements Runnable {

 // Variablendeklaration
  Draw appletThis = null; // Dummy
  Frame appFrame = null; // Unser Frame im ApplicationMode -> Für Parentfeld der Dialoge
  boolean ApplicationMode = false; // Applikation oder Applet?

  TPaint Paint; // Objekt nimmt die Grafikelemente auf
  Dimension dSize; // Temporäre Größe der Zeichenfläche
  int MouseX, MouseY; // Temporäre Mauskoordinaten 
  int startx, starty, endx, endy; // Temporäre Koordinaten des neuen Zeichenobjekts
  boolean ShiftPressed = false; // Shift-gedrückt-Flag
  Image img_surface; // Buffering
  Graphics g_surface; // Buffering

  boolean moving_workplace = false; // Workspace-Wird-Bewegt-Flag  
  boolean selecting_object = false; // Objekt-Auswahl-Modus
  TGraphic selected_object = null; // Das aktuell selektierte Objekt
  boolean moving_object = false; // Objekt-Wird-Bewegt-Flag
  int drawing_object = -1; // -1 = kein Objekt, 1 = Linie, 2 = Rechteck, 3 = Kreis, 22 = gefülltes Rechteck, 33 = gefüllter Kreis
  boolean creating_object = false; // Flag, ob gemalt wird
  boolean connecting_object = false; // Flag, ob Verbindungsgerade gezogen wird
  TGraphic connected_object = null; // Das aktuell selektierte Objekt
  boolean creating_connection = false; // Wird die Verbindungs-Linie gerade gezeichnet?

  Color [] color_set; // Die zur Verfügung stehenden Farben
  boolean draw_filled = false; // gefüllt oder umrandet zeichnen

  MediaTracker dMediaTracker = null; // Der MediaTracker für die bmps
  TRect rect_toolbar = null; // Toolbarabmessungen
  TRect rect_innertoolbar = null; // Das Innere der Toolbar (Icons)
  boolean moving_toolbar = false; // Flag gesetzt, wenn Toolbar bewegt wird
  Image img_toolbar = null; // Das Image-Objekt für die Toolbar
  Image [] img_toolpixhigh; // Die High-Pix der Toolbar
  Image [] img_toolpixpressed; // Die Pressed-Pix der Toolbar
  Image [] img_toolpixhighpressed; // Die HighPressed-Pix der Toolbar
  Image [] img_shadow; // Die Schatten der Toolbars
  int oldActiveToolPix = -1; // Vorhergehendes Toolbar-Pix (für Flickerreduktion)
  int activeToolPix = -1; // Kein Toolbar-Pix wird gezeichnet

  TRect rect_stringbar = null; // stringbarabmessungen
  TRect rect_innerstringbar = null; // Das Innere der stringbar (Icons)
  boolean moving_stringbar = false; // Flag gesetzt, wenn stringbar bewegt wird
  Image img_stringbar = null; // Das Image-Objekt für die stringbar

  TRect rect_stylebar = null;      // Stylebarabmessungen
  TRect rect_innerstylebar = null; // Das Innere der Stylebar (Icons)
  boolean moving_stylebar = false; // Flag gesetzt, wenn Stylebar bewegt wird
  Image img_stylebar = null;       // Das Image-Objekt für die Stylebar
  Image img_colorpanel = null;     // Das Panel für die Colorauswahl
  int color_picking = -1;          // Flag, ob und welche Farbe gewählt wird (1=Vorder, 2=Hinter)

  Image img_hamster = null;        // Nimmt den Hamster auf  
  Image img_laufhamster = null;    // Und der laufende Hamster für den Handlungsreisenden

  boolean showMap = false;         // Flag, ob Kartenhintergrund gemalt wird oder nicht
  Image img_map = null;            // Das anzuzeigende Hintergrundbild

  boolean animationMode = false;   // Variablen für den Animationsmodus des Handlungsreisendenproblems
  int animationStep = -1;          // Aktuelles Objekt, das die Animation abfährt
  TGraph animationGraph = null;    // Der zu animierende Graph
  Thread animationThread = null;   // Der Thread für die saubere Animation


 /** Mit dieser Methode wird der Applikations-/Appletmodus gesetzt
   * @param boolean Mit true wird der Applikationsmodus gesetzt, mit false der Appletmodus
   * @param Frame Der Frame, in dem wir im Applikationsmodus dargestellt werden
   */
 public void setApplicationMode (boolean AppMode, Frame AppFrame) {
    ApplicationMode = AppMode;
    appFrame = AppFrame;
 }

 // Tastatur-Handling
 KeyListener unserKeyListener = new KeyAdapter()
 {
    public void keyPressed(KeyEvent e) { // Taste gedrückt
       if ((e.getKeyCode()==KeyEvent.VK_SHIFT) || (e.getKeyCode()==KeyEvent.VK_S)) { 
          if (!ShiftPressed) {
             ShiftPressed = true; 
             if (creating_object) { repaint(); } // Beim Objekt malen, redrawen -> smooth
          }
          ShiftPressed = true;  repaint();
       }
    }
    public void keyReleased(KeyEvent e) { // Taste losgelassen
      // SHIFT-FLAG-HANDLING
       if ((e.getKeyCode()==KeyEvent.VK_SHIFT) || (e.getKeyCode()==KeyEvent.VK_S)) { 
          if (ShiftPressed) {
             ShiftPressed = false;
             if (creating_object) { repaint(); } // Beim Objekt malen, redrawen -> smooth
          }
          ShiftPressed = false;  repaint();
       }
      // LÖSCHEN MIT TASTEN "DELETE" ODER "D"
       if ((e.getKeyCode()==KeyEvent.VK_DELETE) || (e.getKeyCode()==KeyEvent.VK_D)) { 
          Paint.PaintWorkplace().delete(selected_object);
          repaint(); 
       } 
      // HINTERGRUND-BILD ANZEIGEN MIT TASTE "M"
       if ((e.getKeyCode()==KeyEvent.VK_M)) { 
          if (showMap) { showMap = false; } else { showMap = true; }
          repaint(); 
       } 
      // NÄCHSTEN ANIMATIONSSCHRITT ANZEIGEN MIT TASTE "N" 
       if ((e.getKeyCode()==KeyEvent.VK_N)) {  
          if (animationMode) { 
             animationStep++; 
             if (animationStep<animationGraph.animationSteps()) { 
                animationGraph.setAnimationStep (animationStep); 
                System.out.println ("STEP"+animationStep); 
             } else { 
                animationMode = false; 
                animationGraph.setAnimationStep (-1); 
             } 

             repaint(); 
          } 
       }  
    }
 };

 // Mouse-Handling
 MouseListener unserMouseListener = new MouseAdapter()
 {
    public void mousePressed(MouseEvent e) { // Mouse gedrückt
       MouseX = e.getX();   MouseY = e.getY();       
 
      // Die Statusvariablen/-flags resetten
       creating_object = false;
       creating_connection = false;
       moving_toolbar = false;
       moving_stylebar = false;
       moving_stringbar = false;
       moving_workplace = false;
       color_picking = -1;

      // Ist Mauscursor in der Toolbar
       if (rect_toolbar.IsIn (MouseX, MouseY)) {
            // Ist der Mauscursor am Rand der Toolbar 
             if (!rect_innertoolbar.IsIn (MouseX, MouseY)) {
                moving_toolbar = true;
            // Hier ist der Mauscursor auf den Buttons
             } else {

               // Berechnen, welcher gedrückt wurde
                int col = (MouseX - rect_innertoolbar.x) / 25;
                int row = (MouseY - rect_innertoolbar.y) / 25;
  //              oldActiveToolPix = activeToolPix;
//                activeToolPix = -1; // col + row*3;          

               // 1. Reihe = Zoom, Scrollen, Löschen
                if (row==0) {
                   switch (col) { 
                   case 0: // ZEIGER-SYMBOL -> BENUTZEN ZUM VERSCHIEBEN VON OBJEKTEN 
                      drawing_object = -1;
                      connecting_object = false;
                      if (selecting_object) {
                         selecting_object = false;                       
                      } else selecting_object = true;                      
                      break;                      
                   case 1: // ZOOM -> RÜCK MIT ShiftPressed UND ALS STATUS: SCROLLEN
                      selecting_object = false; 
                      drawing_object = -1;
                      if (!ShiftPressed) { // VERGRÖßERN
                         Paint.PaintSettings().zoom ( Math.sqrt(2) );
                         repaint();
                      } else { // VERKLEINERN
                         Paint.PaintSettings().zoom ( 1 / Math.sqrt(2) );
                         repaint();
                      }
                      break;
                   case 2: // RADIERGUMMI-SYMBOL -> LÖSCHT SELEKTIERTES OBJEKT
                      // selecting_object = false;
                      // drawing_object = -1;
                      if (selected_object!=null) {
             	         Paint.PaintWorkplace().delete(selected_object);
                         repaint(); 
                      }
                      break;                      
                   }
                }

               // Neu, Öffnen, Speichern:
                if (row==1) {
                   switch (col) { 
                   case 0: // NEU
                      selecting_object = false;
                      TNewDrawBox NewDrawBox = new TNewDrawBox(); // New-Dialog
                      NewDrawBox.setPreset ((long)Paint.PaintSettings().maxX+1, (long)Paint.PaintSettings().maxY+1);
                      NewDrawBox.show();
                      if (NewDrawBox.result==1) { // OK gedrückt
                          Paint.PaintWorkplace().clear();
                          Paint.PaintSettings().Xratio = 1;
		          Paint.PaintSettings().Yratio = 1;
                          Paint.PaintSettings().mapStartX = 0;
                          Paint.PaintSettings().mapStartY = 0;
                          Paint.PaintSettings().maxX = (double)NewDrawBox.NewWidth -1;
                          Paint.PaintSettings().maxY = (double)NewDrawBox.NewHeight -1; 
                          repaint();
                      }
                      requestFocus(); // Der Focus ist gerade verlorengegangen, also wieder holen
                      ShiftPressed = false;
                      break;                      
                   case 1: // LADEN (nur als Applikation)
                      if (ApplicationMode) {
                         FileDialog OpenFileDialog = new FileDialog (appFrame, "Bitte wählen Sie eine Datei zum Öffnen", FileDialog.LOAD);
                         OpenFileDialog.show();
                         if (OpenFileDialog.getFile()!=null) {
                            try {
                               Paint.loadFromFile( OpenFileDialog.getDirectory()+OpenFileDialog.getFile() ); 
                               repaint();
                            } catch (java.io.StreamCorruptedException ex1) { 
                               System.out.println ("Konnte Datei nicht öffnen.");
                               new TMessageBox ("Datei-Lese-Fehler", "Die Datei >"+OpenFileDialog.getFile()+"< konnte nicht geöffnet werden.").show();
                            } catch (java.io.IOException ex2) {
                               System.out.println ("Konnte Datei nicht öffnen.");
                               new TMessageBox ("Datei-Lese-Fehler", "Die Datei >"+OpenFileDialog.getFile()+"< konnte nicht geöffnet werden.").show();
                            } catch (java.lang.ClassNotFoundException ex3) {
                               System.out.println ("Formatfehler.");
                               new TMessageBox ("Datei-Format-Fehler", "Die Datei >"+OpenFileDialog.getFile()+"< enthält ungültige Elemente.").show();
                            }
                         }
                         repaint();
                         requestFocus(); // Der Focus ist gerade verlorengegangen, also wieder holen
                         ShiftPressed = false;
                      }
                      break;   
                   case 2: // SPEICHERN (nur als Applikation)
                      if (ApplicationMode) {
                         FileDialog SaveFileDialog = new FileDialog (appFrame, "Bitte wählen Sie eine Datei zum Speichern", FileDialog.SAVE);
                         SaveFileDialog.show();
                         if (SaveFileDialog.getFile()!=null) {
                            try {
                               Paint.saveToFile( SaveFileDialog.getDirectory()+SaveFileDialog.getFile() ); 
                            } catch (java.io.FileNotFoundException ex1) { 
                               System.out.println ("Konnte Datei nicht speichern.");
                               new TMessageBox ("Datei-Schreib-Fehler", "Die Datei >"+SaveFileDialog.getFile()+"< konnte nicht gespeichert werden.").show();
                            } catch (java.io.IOException ex2) {
                               System.out.println ("Konnte Datei nicht speichern.");
                               new TMessageBox ("Datei-Schreib-Fehler", "Die Datei >"+SaveFileDialog.getFile()+"< konnte nicht gespeichert werden.").show();
                            }
                         }
                         requestFocus(); // Der Focus ist gerade verlorengegangen, also wieder holen
                         ShiftPressed = false;
                      }
                      break;
                   }
                }        

               // Wurde untere Reihe gewählt, dann: Welches Zeichenobjekt wurde gewählt     
                if (row==2) { 
                   selecting_object = false;
                   connecting_object = false;
                   switch (col) {
                   case 0: // LINIE 
                      drawing_object = 1; 
                      break;
                   case 1: // RECHTECK
                      if (draw_filled) { 
                         drawing_object = 22;
                      } else {
                         drawing_object = 2; 
                      }
                      break;
                   case 2: // KREIS
                      if (draw_filled) { 
                         drawing_object = 33;
                      } else {
                         drawing_object = 3;
                      }
                      break;
                   }
                } 

                repaint();
             }
      // Ist Cursor in Stylebar?
       } else if (rect_stylebar.IsIn (MouseX, MouseY)) {
         // Ist der Mauscursor am Rand der Stylebar?            
          if (!rect_innerstylebar.IsIn (MouseX, MouseY)) {
             moving_stylebar = true;
         // Also ist Cursor auf den Buttons -> Reaktion
          } else {
            // Berechnen, welcher gedrückt wurde
             int col = (MouseX - rect_innerstylebar.x);

            // Filled-Status-Button
             if (col<25) {
                if (draw_filled) {
                   draw_filled = false;
                   if (drawing_object == 22) { drawing_object = 2; }
                   if (drawing_object == 33) { drawing_object = 3; }
                } else {
                   draw_filled = true;
                   if (drawing_object == 2) { drawing_object = 22; }
                   if (drawing_object == 3) { drawing_object = 33; }
                }
                repaint();
             }
            // Erster ColorPicker -> Vordergrund
             if ((col>24) && (col<67)) {
                color_picking = 1;
                repaint();
             }
            // Zweiter ColorPicker -> Hintergrund
             if (col>66) {
                color_picking = 2;
                repaint();
             }

           //  oldActiveToolPix = activeToolPix;
           //  activeToolPix = -1;
          }

      // Ist Cursor in Stringbar?
       } else if (rect_stringbar.IsIn (MouseX, MouseY)) {
         // Ist der Mauscursor am Rand der Stringbar?
          if (!rect_innerstringbar.IsIn (MouseX, MouseY)) {
             moving_stringbar = true;
         // Also ist Cursor auf den Buttons -> Reaktion
          } else {
            // Berechnen, welcher gedrückt wurde
             int col = (MouseX - rect_innerstringbar.x) / 25;
             int row = (MouseY - rect_innerstringbar.y) / 25;

             TTree thisTree = null;
             TGraphic Graphic = null;
             TGraphicContainer thisContainer = null;
             TStringEditBox StringEditBox = null;
             int xPos;

            // Die Buttons der ersten Reihe der Stringbox
             if (row==0) {
                switch (col) {
                case 0: // Neu-Button
                   if (ShiftPressed) {
                     // Wenn kein Baum markiert, dann neues Baumobjekt erzeugen, sonst aktuelles verwenden
                      if (selected_object==null) {
                         thisTree = new TTree(Paint.PaintSettings());
                         Paint.PaintWorkplace().add(thisTree); 
                      } else {
                         for ( int ic = 0; ic < Paint.PaintWorkplace().count(); ic++) {
                            Graphic = Paint.PaintWorkplace().getItem( ic );
                            if (Graphic instanceof TGraphicContainer) {
                               if ( ((TGraphicContainer)Graphic).isItemOf (selected_object) ) {
                                  if (Graphic instanceof TTree) { thisTree = (TTree)Graphic; }
                                  break;
                               }
                            }
                         }
                         if (thisTree==null) { 
                            thisTree = new TTree(Paint.PaintSettings());
                            Paint.PaintWorkplace().add(thisTree); 
                         }
                      }
   
                      StringEditBox = new TStringEditBox ("");
                      StringEditBox.show();
          
                      if ((StringEditBox.getResult()) && ( !StringEditBox.getString().equals (""))) {
                        // Eingegebenen Text falls nötig in die einzelnen Wörter aufsplitten und Textboxen erzeugen
                         StringTokenizer st = new StringTokenizer(StringEditBox.getString());
                         xPos = Paint.PaintSettings().double2pixX( Paint.PaintSettings().mapStartX + Paint.PaintSettings().maxX /2);
                         while (st.hasMoreTokens()) {
       	                    thisTree.add ( new TTextbox( st.nextToken(), xPos, 20, Paint.PaintSettings() ) ); 
                         }
                         thisTree.arrange();
                         repaint();
                      }
                      requestFocus(); // Der Focus ist gerade verlorengegangen, also wieder holen
                      ShiftPressed = false;

                  // Nur Textbox einfügen (ohne Shift):
                   } else if (!ShiftPressed) {
                      StringEditBox = new TStringEditBox ("");
                      StringEditBox.show();

                      if ((StringEditBox.getResult()) && ( !StringEditBox.getString().equals (""))) {
                        // Textbox mit eingegenem Text erzeugen und mittig plazieren
                         xPos = Paint.PaintSettings().double2pixX( Paint.PaintSettings().mapStartX + Paint.PaintSettings().maxX /2);
     	                 Paint.PaintWorkplace().add ( new TTextbox( StringEditBox.getString(), xPos, 20, Paint.PaintSettings() ) );
                         repaint();
                      }

                      requestFocus(); // Der Focus ist gerade verlorengegangen, also wieder holen
                      ShiftPressed = false;
                   }
                   break;
                case 1:  // Ändern-Button
                  // operiert auf eigenständige Textboxen und auf solchen in Bäumen/Graphen
                   if (selected_object instanceof TTextbox) {
                      thisContainer = null;
                      for ( int ic = 0; ic < Paint.PaintWorkplace().count(); ic++) { // Containerobjekt suchen
                         Graphic = Paint.PaintWorkplace().getItem( ic );
                         if (Graphic instanceof TGraphicContainer) {
                            if ( ((TGraphicContainer)Graphic).isItemOf (selected_object) ) {
                               if (Graphic instanceof TGraphicContainer) { thisContainer = (TGraphicContainer)Graphic; }
                               break;
                            }
                         }
                      }
                     // Wenn Textbox nicht in Container, also freistehend
                      if (thisContainer==null) {
                         StringEditBox = new TStringEditBox (((TTextbox)selected_object).text);
                         StringEditBox.show();
                         requestFocus(); // Der Focus ist gerade verlorengegangen, also wieder holen
                         ShiftPressed = false;

                         if ((StringEditBox.getResult()) && ( !StringEditBox.getString().equals (""))) {
                            ((TTextbox)selected_object).text = StringEditBox.getString();
                            repaint();
                         }
                      } else {
                        // Fallunterscheidung zwischen verschiedenen Containern, nicht ganz OOP, aber ist hier einfacher so
                         if (thisContainer instanceof TTree) {
                                                       
                            StringEditBox = new TStringEditBox (((TTextbox)selected_object).text);
                            StringEditBox.show();
                            requestFocus(); // Der Focus ist gerade verlorengegangen, also wieder holen
                            ShiftPressed = false;

                            if ((StringEditBox.getResult()) && ( !StringEditBox.getString().equals (""))) {
                               thisTree = (TTree)thisContainer;
       	                       thisTree.delete ( selected_object ); 
                               Color saveColor = Paint.PaintSettings().currentColor;
                               Paint.PaintSettings().currentColor = ((TTextbox)selected_object).Pen().color; 
       	                       thisTree.add ( new TTextbox( StringEditBox.getString(), 50, 20, Paint.PaintSettings() ) );
                               Paint.PaintSettings().currentColor = saveColor;
                               thisTree.arrange();
                               repaint();  
                            }
                  
                        /* } else if (thisContainer instanceof TGraph) { */
                         }  
                      }
                   }
                   break;
                case 2:  // Arrangieren-Button: Bei Bäumen: Anordnen und Shift: Bei Graphen Alle verbinden
                  // Arbeitet mit ausgewähltem Baum oder Container
                   if (selected_object!=null) {
                      for ( int ic = 0; ic < Paint.PaintWorkplace().count(); ic++) {
                         Graphic = Paint.PaintWorkplace().getItem( ic );
                         if (Graphic instanceof TGraphicContainer) {
                            if ( ((TGraphicContainer)Graphic).isItemOf (selected_object) ) {
                               // if (Graphic instanceof TTree) { thisTree = (TTree)Graphic; }
                               if (Graphic instanceof TGraphicContainer) { thisContainer = (TGraphicContainer)Graphic; }
                               break;
                            }
                         }
                      }
                      if (thisContainer instanceof TTree) {                         
                        // Neuarrangieren der Baumelemente
                         if (!ShiftPressed) {
                            ((TTree)thisContainer).arrange();
                            repaint();
                         }
                      }
                      if (thisContainer instanceof TGraph) {
                        // Verbinden aller Elemente
                         if (ShiftPressed) {
                            ((TGraph)thisContainer).connectAll();
                         }
                         repaint();                      
                      }  
                   } else { // wenn kein Objekt gewählt, dann Fehlermeldung
                      new TMessageBox ("Kein Graph gewählt", "Bitte wählen Sie ein Objekt in einem Graphen.").show();
                      requestFocus(); 
                      ShiftPressed = false;                     
                   } 
                   break;
                }
            // Die Buttons der zweite Reihe der Stringbox
             } else if (row==1) {
                switch (col) {
                case 0:  // connecting-tool
                   selecting_object = false; // Select-Modus abschalten
                   drawing_object = -1;

                   if (connecting_object) {
                      connecting_object = false;                       
                   } else connecting_object = true;                      
                   repaint();
                   break;
                case 1:  // spannbaum-tool -> Graph muß markiert sein
                   if (selected_object != null) {
                      thisContainer = null;
                      for ( int ic = 0; ic < Paint.PaintWorkplace().count(); ic++) { // Containerobjekt suchen
                         Graphic = Paint.PaintWorkplace().getItem( ic );
                         if (Graphic instanceof TGraphicContainer) {
                            if ( ((TGraphicContainer)Graphic).isItemOf (selected_object) ) {
                               if (Graphic instanceof TGraphicContainer) { thisContainer = (TGraphicContainer)Graphic; }
                               break;
                            }
                         }
                      }
                      if (thisContainer instanceof TGraph) {
                        // Spannbaum eines Teilgraphen
                         if (!ShiftPressed) {
                            if ( ((TGraph)thisContainer).getSTree() != 1 ) { ((TGraph)thisContainer).setSTree(1, selected_object); }
                            else { ((TGraph)thisContainer).setSTree(0, selected_object); }
                        // Spannbaum aller Teilgraphen
                         } else {
                            // ((TGraph)thisContainer).connectAll();
                            if ( ((TGraph)thisContainer).getSTree() != 2 ) { ((TGraph)thisContainer).setSTree(2, selected_object); }
                            else { ((TGraph)thisContainer).setSTree(0, selected_object); }
                         }
                         repaint();                      
                      }  // !(thisContainer instanceof TGraph))
                   } else { // wenn kein Objekt gewählt, dann Fehlermeldung
                      new TMessageBox ("Kein Graph gewählt", "Bitte wählen Sie ein Objekt in einem Graphen.").show();
                      requestFocus(); 
                      ShiftPressed = false;                     
                   } 
                   break;
                case 2:  // Handlungsreisender -> Graph muß markiert sein
                   if (selected_object != null) {
                      thisContainer = null;
                      for ( int ic = 0; ic < Paint.PaintWorkplace().count(); ic++) { // Containerobjekt suchen
                         Graphic = Paint.PaintWorkplace().getItem( ic );
                         if (Graphic instanceof TGraphicContainer) {
                            if ( ((TGraphicContainer)Graphic).isItemOf (selected_object) ) {
                               if (Graphic instanceof TGraphicContainer) { thisContainer = (TGraphicContainer)Graphic; }
                               break;
                            }
                         }
                      }
                      if (thisContainer instanceof TGraph) {
                        // Handlungsreisender normal
                         if (!ShiftPressed) {
                            if ( ((TGraph)thisContainer).getSTree() != 3 ) { 
                               ((TGraph)thisContainer).setSTree(3, selected_object);
                               repaint();
                               animateRoute((TGraph)thisContainer);
                            } else { 
                               ((TGraph)thisContainer).setSTree(0, selected_object); 
                               repaint();
                            }
                        // Handlungsreisender kantenlos
                         } else {
                            if ( ((TGraph)thisContainer).getSTree() != 4 ) { 
                               ((TGraph)thisContainer).setSTree(4, selected_object); 
                               repaint();
                               animateRoute((TGraph)thisContainer);
                            } else { 
                               repaint();
                               ((TGraph)thisContainer).setSTree(0, selected_object); 
                            }
                         }                        
                      }  
                   } else { // wenn kein Objekt gewählt, dann Fehlermeldung
                      new TMessageBox ("Kein Graph gewählt", "Bitte wählen Sie ein Objekt in einem Graphen.").show();
                      requestFocus(); 
                      ShiftPressed = false;                     
                   } 
                   break;
                }
             }

            // oldActiveToolPix = activeToolPix;
            // activeToolPix = -1;                 
          }
      // also nicht in Tool-,String-, oder Stylebar, sondern auf dem Rest der Zeichenfläche
       } else {        
          if (drawing_object != -1) {
             creating_object = true;
             startx = MouseX;  starty = MouseY;
         // Das Auswahlwerkzeug und das Connecting-Tool
          } else if ((selecting_object) || (connecting_object)) { // OBJEKT-FANG-MODUS
    	     TGraphic Graphic;
             boolean oneIsSelected = false;

            // Deselktieren aktuell angewählter Objekte
             Paint.PaintWorkplace().setSelected( false );
             selected_object = null; // Kein Objekt ausgewählt
             moving_object = false;

            // Alle Objekte durchlaufen und checken, ob Mauscursor drin ist
             for (int i = Paint.PaintWorkplace().count()-1; i >= 0; i--) {
               // Wir müssen hier vorrübergehend zwischen Baum-Containern und anderen Objekten unterscheiden
                Graphic = Paint.PaintWorkplace().getItem(i);

                if ((Graphic instanceof TGraphicContainer) && (selected_object==null)) {
                 
                   TGraphic NodeGraphic = Graphic.getObjectAt ( MouseX, MouseY );
                   if (NodeGraphic != null) { selected_object = NodeGraphic; NodeGraphic.setSelected( true ); moving_object = true; }
                   repaint();
 
                } else if (selected_object==null) {
                   if (Graphic.isInside (MouseX, MouseY)) {
                      if (!oneIsSelected) { selected_object = Graphic; Graphic.setSelected( true ); moving_object = true; oneIsSelected = true; }
                      else { Graphic.setSelected( false ); } 
                      repaint();
                   } else {
                      Graphic.setSelected( false );
                      repaint();
                   }
                }
             }   

            // Sonderbehandlung: Die Linie des Connecting-Tools
             if ((selected_object!=null) && (connecting_object)) {
                creating_connection = true;
                moving_object = false;
                startx = MouseX;  starty = MouseY;
             }

         // WENN NUR SO GEKLICKT, DANN WIRD WORKSPACE BEWEGT
          } else { 
            // Nur Scrollen, wenn die Zeichenfläche > als Fenster ist
             if (( Paint.PaintSettings().getPixelMaxX()+1 > getSize().width -1 ) || ( Paint.PaintSettings().getPixelMaxY()+1 > getSize().height -1 )) {
                moving_workplace = true;
             }
          }

       }
    }

    public void mouseReleased(MouseEvent e) { // Mouse gedrückt
       endx = e.getX();  endy = e.getY();

      // Objekte in Workspace einfügen
       if (creating_object){
          int x1,x2,y1,y2;
   
          x1 = startx;    y1 = starty;
          x2 = startx - endx;   y2 = starty - endy;
          if (x2 < 0 )  { x2 = -x2; }
          if (y2 < 0 )  { y2 = -y2; }
 
         // Mit gedrückter Shift-Taste: gleiche Seitenverhältnisse
          if (ShiftPressed) {
             if (x2 < y2) { y2 = x2; }
             else { x2 = y2; }
          }
  
         // Orientierungs-Korrektur
          if (startx>endx) { x1 = x1 - x2; } 
          if (starty>endy) { y1 = y1 - y2; } 

         // Die einzelnen Objekte erzeugen
          TRectangle thisRectangle;
          TCircle thisCircle;
          switch ( drawing_object ) {
          case 1: // LINIE
             TLine thisLine = new TLine( startx, starty, endx, endy, Paint.PaintSettings() );
             Paint.PaintWorkplace().add(thisLine);
             Paint.PaintWorkplace().setSelected (false);
             thisLine.setSelected (true);
             selected_object = thisLine;
             repaint();             
             break;
          case 2: // RECHTECK
             thisRectangle = new TRectangle( x1, y1, x2, y2, false, Paint.PaintSettings() );
             Paint.PaintWorkplace().add(thisRectangle);
             Paint.PaintWorkplace().setSelected (false);
             thisRectangle.setSelected (true);
             selected_object = thisRectangle;
             repaint();             
             break;
          case 3: // KREIS/ELLIPSE
             thisCircle = new TCircle( x1, y1, x2, y2, false, Paint.PaintSettings() );
             Paint.PaintWorkplace().add(thisCircle);
             Paint.PaintWorkplace().setSelected (false);
             thisCircle.setSelected (true);
             selected_object = thisCircle;
             repaint();             
             break;
          case 22: // RECHTECK GEFÜLLT
             thisRectangle = new TRectangle( x1, y1, x2, y2, true, Paint.PaintSettings() );
             Paint.PaintWorkplace().add(thisRectangle);
             Paint.PaintWorkplace().setSelected (false);
             thisRectangle.setSelected (true);
             selected_object = thisRectangle;
             repaint();             
             break;
          case 33: // KREIS/ELLIPSE GEFÜLLT
             thisCircle = new TCircle( x1, y1, x2, y2, true, Paint.PaintSettings() );
             Paint.PaintWorkplace().add(thisCircle);
             Paint.PaintWorkplace().setSelected (false);
             thisCircle.setSelected (true);
             selected_object = thisCircle;
             repaint();             
             break;
          }   


       } else if (color_picking > 0) {
         // Farbe holen
          if (new TRect (rect_innerstylebar.x + 25 + ((color_picking-1)*42), 
                         rect_innerstylebar.y + rect_innerstylebar.height, 
                         42, 177 ).IsIn (endx, endy)) {
             if (color_picking==1) {
                int new_color_num = (endy - rect_innerstylebar.y - rect_innerstylebar.height) / 13; 
                if (new_color_num > 12) { new_color_num = 12; }
                Paint.PaintSettings().currentColor = color_set[new_color_num];
                if ((selected_object!=null) && (selected_object instanceof TShapeGraphic)) { // aktuelles Objekt einfärben
                   ((TShapeGraphic)selected_object).Pen().color = Paint.PaintSettings().currentColor;
                   repaint();
                }
             } else {
                int new_color_num = (endy - rect_innerstylebar.y - rect_innerstylebar.height) / 13; 
                if (new_color_num > 12) { new_color_num = 12; }
                Paint.PaintSettings().currentBGColor = color_set[new_color_num];
             }
          }
          repaint();
       } else if ((moving_object) && (selected_object!=null)) {
          selected_object.setLeft ( selected_object.getLeft() - Paint.PaintSettings().pix2doubleWidth (MouseX - endx) );
          selected_object.setTop ( selected_object.getTop()  - Paint.PaintSettings().pix2doubleHeight (MouseY - endy) );
          repaint();
          moving_object = false; // nachdem losgelassen wurde ist Schluß mit Bewegen!
       } else if ((connecting_object) && (creating_connection)) {
          creating_connection = false;

     /*    // Deselktieren aktuell angewählter Objekte
          Paint.PaintWorkplace().setSelected( false );
        // nja nja...
          selected_object = null;
*/
          TGraphic Graphic = null;
          boolean oneIsSelected = false;
          connected_object = null;
          TGraphicContainer connected_container = null;
          TGraphicContainer selected_container = null;

         // Alle Objekte durchlaufen und checken, ob Mauscursor drin ist
          for (int i = Paint.PaintWorkplace().count()-1; i >= 0; i--) {
            // Wir müssen hier vorrübergehend zwischen Baum-Containern und anderen Objekten unterscheiden
             Graphic = Paint.PaintWorkplace().getItem(i);

            // Objekt unter Mauskoordinaten suchen
             if ((Graphic instanceof TGraphicContainer) && (connected_object==null)) {                
                TGraphic NodeGraphic = Graphic.getObjectAt ( endx, endy );
                if (NodeGraphic != null) { connected_object = NodeGraphic; connected_container = (TGraphicContainer)Graphic; }
             } else if (connected_object==null) {
                if (Graphic.isInside (endx, endy)) {
                   if (!oneIsSelected) { connected_object = Graphic; oneIsSelected = true; }
                }
             }

            // Falls vorhanden, den Container des ersten Objekts (selected) suchen
             if ((Graphic instanceof TGraphicContainer) && (selected_container==null)) {
                if (((TGraphicContainer)Graphic).isItemOf (selected_object)) { selected_container = (TGraphicContainer)Graphic; }
             } 
 
          }           
 
          connectObjects ( selected_container, selected_object, connected_container, connected_object );

          if (selected_object!=null) { selected_object.setSelected (false); selected_object = null; }
          connected_object = null;       

          repaint();
       }

      // Statusflags resetten
       moving_toolbar = false;
       moving_stylebar = false;
       moving_stringbar = false;
       moving_object = false;
       creating_object = false;     
       creating_connection = false;
       moving_workplace = false;
       color_picking = -1;
    }

    public void mouseClicked(MouseEvent e) { // Zurücksetzen
       MouseX = e.getX();   MouseY = e.getY();    // if (e.getClickCount()==2) { // Bei Doppelklick

       /*} else if (activeToolPix != -1) { 
          activeToolPix = -1;  
          repaint(); 
       }*/
    }
 };

 /** Verbindet zwei Objekte 
   * @param TGraphicContainer Der Container des ersten Objekts (falls kein Container, dann null)
   * @param TGraphic Das erste Objekt
   * @param TGraphicContainer Der Container des zweiten Objekts (falls kein Container, dann null)
   * @param TGraphic Das zweite Objekt
   */
 private void connectObjects ( TGraphicContainer selected_container, TGraphic selected_object, TGraphicContainer connected_container, TGraphic connected_object ) {

   // rausspringen, wenn eines oder beide Objekte null sind
    if ((selected_object==null) || (connected_object==null)) { return; }  

   // Fallunterscheidung nach Container-Vorhandensein:
    TGraph thisGraph = null;
    TGraphic thisGraphic = null;

   // Keines der Objekte hat einen Container:
    if ((selected_container==null) && (connected_container==null)) {
        
       thisGraph = new TGraph (Paint.PaintSettings()); 
       thisGraph.add ( selected_object );
       thisGraph.add ( connected_object );
       thisGraph.connect ( selected_object, connected_object );

       Paint.PaintWorkplace().delete ( selected_object );
       Paint.PaintWorkplace().delete ( connected_object );  

       Paint.PaintWorkplace().add ( thisGraph );

       repaint ();
       return;      
    }

   // Das erste Objekt hat einen Container, das zweite nicht: zweites zum ersten Container hinzufügen
    if ((selected_container!=null) && (connected_container==null)) {

       if (selected_container instanceof TTree) {
          thisGraph = new TGraph (Paint.PaintSettings()); 
          thisGraph.add ( selected_container );
          thisGraph.add ( connected_object );
          thisGraph.connect ( selected_object, connected_object );

          Paint.PaintWorkplace().delete ( selected_container );
          Paint.PaintWorkplace().delete ( connected_object );  

          Paint.PaintWorkplace().add ( thisGraph );

          repaint ();
          return;          
       }

       thisGraph = (TGraph)selected_container;
       thisGraphic = connected_object;
       Paint.PaintWorkplace().delete ( connected_object );      
       thisGraph.add ( thisGraphic );
       thisGraph.connect ( selected_object, thisGraphic );
 
       repaint ();
       return;      
    }

   // Das zweite Objekt hat einen Container, das erste nicht: erstes zum zweiten Container hinzufügen
    if ((selected_container==null) && (connected_container!=null)) {

       if (connected_container instanceof TTree) {
          thisGraph = new TGraph (Paint.PaintSettings()); 
          thisGraph.add ( connected_container );
          thisGraph.add ( selected_object );
          thisGraph.connect ( selected_object, connected_object );

          Paint.PaintWorkplace().delete ( connected_container );
          Paint.PaintWorkplace().delete ( selected_object );  

          Paint.PaintWorkplace().add ( thisGraph );

          repaint ();
          return;          
       }

       thisGraph = (TGraph)connected_container;
       thisGraphic = selected_object;
       Paint.PaintWorkplace().delete ( selected_object );  
       thisGraph.add ( thisGraphic );
       thisGraph.connect ( thisGraphic, connected_object );

       repaint ();
       return;      
    }

   // Beide Objekte haben Container, die Container werden gemergt 
    if ((selected_container!=null) && (connected_container!=null)) {

       if ((selected_container == connected_container) && (!(selected_container instanceof TTree))) {
         if (((TGraph)selected_container).isRelated( selected_object, connected_object )) {
            ((TGraph)selected_container).deconnect ( selected_object, connected_object );
            repaint ();
            return;          
         } else {
            ((TGraph)selected_container).connect ( selected_object, connected_object );
            repaint ();
            return;          
         }
       }

       if ((connected_container instanceof TTree) && (selected_container instanceof TGraph)) {
          thisGraph = (TGraph)selected_container;
          thisGraph.add ( connected_container );
          thisGraph.connect ( selected_object, connected_object );
          Paint.PaintWorkplace().delete ( connected_container );  

          repaint ();
          return;          
       }
       if ((selected_container instanceof TTree) && (connected_container instanceof TGraph)) {
          thisGraph = (TGraph)connected_container;
          thisGraph.add ( selected_container );
          thisGraph.connect ( selected_object, connected_object );
          Paint.PaintWorkplace().delete ( selected_container );  

          repaint ();
          return;          
       }
       if ((selected_container instanceof TTree) && (connected_container instanceof TTree)) {
          thisGraph = new TGraph (Paint.PaintSettings()); 
          thisGraph.add ( connected_container );
          thisGraph.add ( selected_container );
          thisGraph.connect ( selected_object, connected_object );

          Paint.PaintWorkplace().delete ( connected_container );  
          Paint.PaintWorkplace().delete ( selected_container );  
          Paint.PaintWorkplace().add ( thisGraph );

          repaint ();
          return;          
       }

       thisGraph = (TGraph)selected_container;
       thisGraph.add ( connected_container );
       thisGraph.connect ( selected_object, connected_object );
       Paint.PaintWorkplace().delete ( connected_container );  

       repaint ();
       return;      
    }

 }

 /** Animiert den Weg des Handlungsreisenden auf dem gewählten Graphen
   * @param TGraph Der zu animierende Graph
   */
 private void animateRoute (TGraph thisGraph) {

    animationMode = true; 
    animationStep = 0;
    animationGraph = thisGraph;

    animationGraph.setAnimationStep (0); 
    repaint();

    return;
 } 

 // Mousebewegungshandling
 MouseMotionListener unserMotionListener = new MouseMotionAdapter()
 {
    // Methode wird aufgerufen, wenn sich der Mauscursor bewegt hat (nicht gedragt!)
    public void mouseMoved(MouseEvent e) {
       endx = e.getX();   endy = e.getY();
             
      // High-Lighting der Buttons implementieren    
       if (rect_innertoolbar.IsIn(endx,endy)) {
 
         // Jetzt checken, welcher Button gedrawt werden muß
          int col = (endx - rect_innertoolbar.x) / 25;
          int row = (endy - rect_innertoolbar.y) / 25;
          oldActiveToolPix = activeToolPix;
          activeToolPix = col + row*3;          
          if (oldActiveToolPix != activeToolPix) { repaint(); }

       } else if (rect_innerstylebar.IsIn(endx,endy)) {
          if (endx-rect_innerstylebar.x < 25) {
             oldActiveToolPix = activeToolPix;
             activeToolPix = 9; // Der Filled-Button
             repaint();
          } else if (endx-rect_innerstylebar.x < 67) {
             oldActiveToolPix = activeToolPix;    
             activeToolPix = 10;  
             repaint();
          } else {
             oldActiveToolPix = activeToolPix;    
             activeToolPix = 11;  
             repaint();
          }
       } else if (rect_innerstringbar.IsIn(endx,endy)) {

         // Jetzt checken, welcher Button gedrawt werden muß
          int col = (endx - rect_innerstringbar.x) / 25;
          int row = (endy - rect_innerstringbar.y) / 25;
          oldActiveToolPix = activeToolPix;
          activeToolPix = 12+col+row*3;
          if (oldActiveToolPix != activeToolPix) { repaint(); }

       } else if (activeToolPix != -1) { 
          oldActiveToolPix = activeToolPix;
          activeToolPix = -1;  
          repaint();
       }

       MouseX = e.getX();  MouseY = e.getY();
    }

    // Methode wird beim Draggen (gedrückter Mausbutton+Bewegung) aufgerufen
    public void mouseDragged(MouseEvent e) {
 
      // Abmessungen unserer Zeichenfläche holen
       dSize = getSize (); // .height, .width sind die Maße...

      // Toolbar wird bewegt
       if (moving_toolbar) {
          rect_toolbar.x -= MouseX - e.getX();
          if (rect_toolbar.x + rect_toolbar.width/2 > dSize.width) {
             rect_toolbar.x = dSize.width - rect_toolbar.width/2;
          }
          if (rect_toolbar.x + rect_toolbar.width/2 < 0) {
             rect_toolbar.x = - rect_toolbar.width/2;
          }
          rect_toolbar.y -= MouseY - e.getY();
          if (rect_toolbar.y + rect_toolbar.height/2 > dSize.height) {
             rect_toolbar.y = dSize.height - rect_toolbar.height/2;
          }
          if (rect_toolbar.y < 0) {
             rect_toolbar.y = 0;
          }
          rect_innertoolbar.x = rect_toolbar.x+5;
          rect_innertoolbar.y = rect_toolbar.y+20;

          repaint();

          MouseX = e.getX(); // Neue "alte" Werte Zwischenspeichern
          MouseY = e.getY();

      // Stringbar wird bewegt
       } else if (moving_stringbar) {
          rect_stringbar.x -= MouseX - e.getX();
          if (rect_stringbar.x + rect_stringbar.width/2 > dSize.width) {
             rect_stringbar.x = dSize.width - rect_stringbar.width/2;
          }
          if (rect_stringbar.x + rect_stringbar.width/2 < 0) {
             rect_stringbar.x = - rect_stringbar.width/2;
          }
          rect_stringbar.y -= MouseY - e.getY();
          if (rect_stringbar.y + rect_stringbar.height/2 > dSize.height) {
             rect_stringbar.y = dSize.height - rect_stringbar.height/2;
          }
          if (rect_stringbar.y < 0) {
             rect_stringbar.y = 0;
          }
          rect_innerstringbar.x = rect_stringbar.x+5;
          rect_innerstringbar.y = rect_stringbar.y+20;

          repaint();

          MouseX = e.getX(); // Neue "alte" Werte Zwischenspeichern
          MouseY = e.getY();

      // Stylebar wird bewegt
       } else if (moving_stylebar) {
          rect_stylebar.x -= MouseX - e.getX();
          if (rect_stylebar.x + rect_stylebar.width/2 > dSize.width) {
             rect_stylebar.x = dSize.width - rect_stylebar.width/2;
          }
          if (rect_stylebar.x + rect_stylebar.width/2 < 0) {
             rect_stylebar.x = - rect_stylebar.width/2;
          }
          rect_stylebar.y -= MouseY - e.getY();
          if (rect_stylebar.y + rect_stylebar.height/2 > dSize.height) {
             rect_stylebar.y = dSize.height - rect_stylebar.height/2;
          }
          if (rect_stylebar.y < 0) {
             rect_stylebar.y = 0;
          }
          rect_innerstylebar.x = rect_stylebar.x+5;
          rect_innerstylebar.y = rect_stylebar.y+20;

          repaint();

          MouseX = e.getX(); // Neue "alte" Werte Zwischenspeichern
          MouseY = e.getY();
      // Grafikelement wird erzeugt
       } else if (creating_object) {
             switch (drawing_object) {
             default:
                startx = MouseX;  starty = MouseY;
                endx = e.getX();  endy = e.getY();
                repaint();
                break;
             }
       } else if (moving_workplace) { // SCROLLEN      
          Paint.PaintSettings().move (MouseX - e.getX(), MouseY - e.getY());
          repaint();   
          MouseX = e.getX();  MouseY = e.getY();
       } else if ((selecting_object) && (moving_object) && (selected_object != null)) {
          selected_object.setLeft ( selected_object.getLeft() - Paint.PaintSettings().pix2doubleWidth (MouseX - e.getX()) );
          selected_object.setTop ( selected_object.getTop()  - Paint.PaintSettings().pix2doubleHeight (MouseY - e.getY()) );
          repaint();
          MouseX = e.getX();  MouseY = e.getY();
       } else if ((connecting_object) && (creating_connection)) {
          startx = MouseX;  starty = MouseY;
          endx = e.getX();  endy = e.getY();
          repaint();
       }
    }
 };


 /** Die Paint-Methode des JavaMalprogramms
   * @param Graphics Das Java-Grafik-Ausgabe-Objekt 
   */  
 public void paint (Graphics g) {

   // Zeichen der einzelnen Bildschirmelemente:

   // 1.1 Für den Handlungsreisenden: Soll Hintergrundbild gezeichnet werden?
    if (showMap) {
       g.drawImage (img_map, 0, 0, Paint.PaintSettings().double2pixWidth (Paint.PaintSettings().maxX), Paint.PaintSettings().double2pixHeight (Paint.PaintSettings().maxY), appletThis);
    }

   // 1.2 Alte aus Datenbank zeichnen
    TGraphic Graphic;
    if (Paint.PaintWorkplace().count() > 0) {
       for (int i = 0; i<Paint.PaintWorkplace().count();i++){
          Graphic = Paint.PaintWorkplace().getItem(i);
          Graphic.paint( g );  // Objekte zeichnen sich selbst neu
       }
    }

   // 1.3 Beim Handlungsreisenden wird die aktuell zurückgelegte Wegstrecke in 
   // der linken oberen Ecke angezeigt
    if (animationMode) {
       double routeLen = 0;
       routeLen = animationGraph.getAnimationLength();
       String text = (new Double(routeLen)).toString();
       g.setColor (Color.black);
       g.drawString( text, 5, g.getFontMetrics().getHeight() );
    }


   // 2. Aktuelles Zeichenobjekt ausgeben
    int x, y, breite, hoehe;
    x = startx;   y = starty;
    breite = endx - startx;   hoehe =  endy - starty;
    if (breite < 0 )  { breite = -breite;}
    if (hoehe < 0 )  { hoehe = -hoehe;}

   // Mit gedrückter Shift-Taste: gleiche Seitenverhältnisse
    if (ShiftPressed) {
       if (breite < hoehe) {hoehe = breite;}
       else {breite = hoehe;}
    }

   // Orientierungs-Korrektur
    if (startx>endx) { x = startx - breite; } else { x = startx; }
    if (starty>endy) { y = starty - hoehe; } else { y = starty; }

    if (creating_object) {
       switch (drawing_object) {
       case 1: // LINIE
          g.setColor ( Paint.PaintSettings().currentColor );
          g.drawLine ( startx, starty, endx, endy );
          break;
       case 2: //Rechteck
          g.setColor ( Paint.PaintSettings().currentColor );            
          g.drawRect ( x, y, breite, hoehe );
          break;
       case 3: //Kreis
          g.setColor ( Paint.PaintSettings().currentColor );
          g.drawOval ( x, y, breite, hoehe );
          break;
       case 22: //gefülltes Rechteck
          g.setColor ( Paint.PaintSettings().currentColor );
          g.fillRect ( x, y, breite, hoehe );
          break;
       case 33: //gefüllter Kreis
          g.setColor ( Paint.PaintSettings().currentColor );
          g.fillOval ( x, y, breite, hoehe );
          break;
       }
    }    


   // Connecting-Linie einzeichnen
    if ((connecting_object) && (creating_connection)) {
       g.setColor ( new Color ( 0, 0, 0) );
       g.drawLine ( startx, starty, endx, endy );           
    }


   // Wenn Zeichenfläche kleiner als Frame ist, dann graue Freiflächen einzeichnen
    if (( Paint.PaintSettings().getPixelMaxX()+1 < getSize().width -1 ) || ( Paint.PaintSettings().getPixelMaxY()+1 < getSize().height -1 )) {
       g.setColor (new Color(80,80,80));
       g.fillRect ( Paint.PaintSettings().getPixelMaxX()+1, 0, getSize().width - Paint.PaintSettings().getPixelMaxX()+1, getSize().height );
       g.fillRect ( 0, Paint.PaintSettings().getPixelMaxY()+1, Paint.PaintSettings().getPixelMaxX()+1, getSize().height - Paint.PaintSettings().getPixelMaxY()+1);
    }

   
   // SHIFT-STATUS MALEN 
    if (ShiftPressed) {
       g.drawImage ( img_hamster, Paint.PaintSettings().frameWidth-60, 5, appletThis );
       /* g.setColor ( Color.yellow );
       g.fillRect ( Paint.PaintSettings().frameWidth-50, 10, 40, 10); */
    }

   // 3. Stringbar wird über Bild und Style-/ToolBar gezeichnet
    g.drawImage ( img_stringbar, rect_stringbar.x, rect_stringbar.y, appletThis );

   // Die Textbox-Buttons zeichnen, wenn nötig
    if (activeToolPix==12) { // Neue Textbox
       g.drawImage ( img_toolpixhigh[11], rect_innerstringbar.x, rect_innerstringbar.y, appletThis );
    }
    if (activeToolPix==13) { // Edit Textbox
       g.drawImage ( img_toolpixhigh[12], rect_innerstringbar.x +25, rect_innerstringbar.y, appletThis );
    }
    if (activeToolPix==14) { // Del Textbox
       g.drawImage ( img_toolpixhigh[13], rect_innerstringbar.x +50, rect_innerstringbar.y, appletThis );
    }
    if (activeToolPix != 15) { // CONNECTING-TOOL
       if (connecting_object) {
          g.drawImage ( img_toolpixpressed[14], rect_innerstringbar.x, rect_innerstringbar.y +25, appletThis );
       }
    } else { // if activeToolPix == 15 
       if (connecting_object) {
          g.drawImage ( img_toolpixhighpressed[14], rect_innerstringbar.x, rect_innerstringbar.y +25, appletThis );
       } else {
          g.drawImage ( img_toolpixhigh[14], rect_innerstringbar.x, rect_innerstringbar.y +25, appletThis );
       }
    }
    if (activeToolPix==16) { // Wald zeichen (Kirsche)
       g.drawImage ( img_toolpixhigh[15], rect_innerstringbar.x +25, rect_innerstringbar.y +25, appletThis );
    }
    if (activeToolPix==17) { // Handlungsreisender
       g.drawImage ( img_toolpixhigh[16], rect_innerstringbar.x +50, rect_innerstringbar.y +25, appletThis );
    }


   // 4. Stylebar wird über Bild gezeichnet
    g.drawImage ( img_stylebar, rect_stylebar.x, rect_stylebar.y, appletThis );

   // Die aktuellen Farben hinmalen (fillRect)
    if (activeToolPix==10) { // Selektor Vordergrundfarbe
       g.drawImage ( img_toolpixhigh[10], rect_innerstylebar.x +25, rect_innerstylebar.y, appletThis );
    }
    if (activeToolPix==11) { // Selektor Hintergrundfarbe
       g.drawImage ( img_toolpixhigh[10], rect_innerstylebar.x +25+42, rect_innerstylebar.y, appletThis );
    }
    g.setColor ( Paint.PaintSettings().currentColor );
    g.fillRect ( rect_innerstylebar.x + 30, rect_innerstylebar.y + 6, 24, 12);
    g.setColor ( Paint.PaintSettings().currentBGColor );
    g.fillRect ( rect_innerstylebar.x + 72, rect_innerstylebar.y + 6, 24, 12);

   // Filled-Button, wenn nötig
    if (activeToolPix != 9) {
       if (draw_filled) {
          g.drawImage ( img_toolpixpressed[9], rect_innerstylebar.x, rect_innerstylebar.y, appletThis );
       }
    } else { // if == 9
       if (draw_filled) {
          g.drawImage ( img_toolpixhighpressed[9], rect_innerstylebar.x, rect_innerstylebar.y, appletThis );
       } else {
          g.drawImage ( img_toolpixhigh[9], rect_innerstylebar.x, rect_innerstylebar.y, appletThis );
       }
    }

   // Wenn color_picker, dann malen
    if (color_picking > 0) { // Vordergrund- oder Hintergrundfarbe auswählen
      // Panel zeichnen        
       g.drawImage ( img_colorpanel, rect_innerstylebar.x + 25 + ((color_picking-1)*42), rect_innerstylebar.y + rect_innerstylebar.height, appletThis );

      // Die Farbbalken zeichnen
       int i = 0;
       for (i = 0; i < 13; i++) {
          g.setColor ( color_set[i] );
          g.fillRect ( rect_innerstylebar.x + 30 + ((color_picking-1)*42), rect_innerstylebar.y + rect_innerstylebar.height + 5 + i*13, 31, 11);
       } 
    }


   // 5. Toolbar wird über Bild und StyleBar gezeichnet
    g.drawImage ( img_toolbar, rect_toolbar.x, rect_toolbar.y, appletThis );

    if ((activeToolPix == 1) || (activeToolPix == 2) || (activeToolPix == 3) || (activeToolPix == 4) || (activeToolPix == 5)) {
       g.drawImage ( img_toolpixhigh[activeToolPix], rect_innertoolbar.x + (activeToolPix%3)*25, rect_innertoolbar.y + (activeToolPix / 3) * 25, appletThis );
    } // Die ersten 6 Buttons, naja...

    if (activeToolPix != 0) {
       if (selecting_object) {
          g.drawImage ( img_toolpixpressed[0], rect_innertoolbar.x, rect_innertoolbar.y, appletThis );
       }
    } else { // if activeToolPix == 0 -> POINTER
       if (selecting_object) {
          g.drawImage ( img_toolpixhighpressed[0], rect_innertoolbar.x, rect_innertoolbar.y, appletThis );
       } else {
          g.drawImage ( img_toolpixhigh[0], rect_innertoolbar.x, rect_innertoolbar.y, appletThis );
       }
    }

    if (activeToolPix != 6) {
       if (drawing_object == 1) {
          g.drawImage ( img_toolpixpressed[6], rect_innertoolbar.x, rect_innertoolbar.y +50, appletThis );
       }
    } else { // if == 6
       if (drawing_object == 1) {
          g.drawImage ( img_toolpixhighpressed[6], rect_innertoolbar.x, rect_innertoolbar.y +50, appletThis );
       } else {
          g.drawImage ( img_toolpixhigh[6], rect_innertoolbar.x, rect_innertoolbar.y +50, appletThis );
       }
    }

    if (activeToolPix != 7) {
       if ((drawing_object == 2) || (drawing_object == 22)) {
          g.drawImage ( img_toolpixpressed[7], rect_innertoolbar.x +25, rect_innertoolbar.y +50, appletThis );
       }
    } else { // if == 7
       if ((drawing_object == 2) || (drawing_object == 22)) {
          g.drawImage ( img_toolpixhighpressed[7], rect_innertoolbar.x +25, rect_innertoolbar.y +50, appletThis );
       } else {
          g.drawImage ( img_toolpixhigh[7], rect_innertoolbar.x +25, rect_innertoolbar.y +50, appletThis );
       }
    }

    if (activeToolPix != 8) {
       if ((drawing_object == 3) || (drawing_object == 33)) {
          g.drawImage ( img_toolpixpressed[8], rect_innertoolbar.x +50, rect_innertoolbar.y +50, appletThis );
       }
    } else { // if == 8
       if ((drawing_object == 3) || (drawing_object == 33)) {
          g.drawImage ( img_toolpixhighpressed[8], rect_innertoolbar.x +50, rect_innertoolbar.y +50, appletThis );
       } else {
          g.drawImage ( img_toolpixhigh[8], rect_innertoolbar.x +50, rect_innertoolbar.y +50, appletThis );
       }
    }
 }

 /** Die Update-Methode der Klasse (ruft paint auf...)
   * @param Graphics Das Java-Grafik-Ausgabe-Objekt 
   */
 public void update (Graphics g) {

   // BufferImage anlegen, wenn nicht
    if (img_surface == null) {
       img_surface = createImage (getSize().width, getSize().height);
       g_surface = img_surface.getGraphics();
    }

   // BufferImage resizen, wenn Frame geresizet wurde
    if ((Paint.PaintSettings().frameWidth != getSize().width) || (Paint.PaintSettings().frameHeight != getSize().height)) {
       img_surface = createImage (getSize().width, getSize().height);
       g_surface = img_surface.getGraphics();
    }       

   // Neue Abmessungen an Objektsystem mitteilen
    Paint.PaintSettings().frameWidth = getSize().width;   
    Paint.PaintSettings().frameHeight = getSize().height;

   // Buffer säubern und kopieren
    setBackground (Paint.PaintSettings().currentBGColor);
    dSize = getSize();
    g_surface.setColor (Paint.PaintSettings().currentBGColor);
    g_surface.fillRect (0, 0, dSize.width, dSize.height);

    paint (g_surface);
    // alphaToolbar (img_surface, g_surface);
    g.drawImage (img_surface, 0, 0, appletThis);
 }

 public int handlesinglepixel(int x, int y, int pixel) {
    int alpha = (pixel >> 24) & 0xff;
    int red   = (pixel >> 16) & 0xff;
    int green = (pixel >>  8) & 0xff;
    int blue  = (pixel      ) & 0xff;

    red = 0;
    green = 0;
    blue = 0;
    alpha = 128;

   // Deal with the pixel as necessary...
    return ( (alpha << 24) + (red << 16) + (green << 8) + (blue) );

 }

 public void alphaToolbar (Image img_surface, Graphics g) {

    int x = rect_toolbar.x+rect_toolbar.width;  int y = rect_toolbar.y;
    int w = 10;  int h = rect_toolbar.height;


    if (img_shadow[0] == null) {

    int[] pixels = new int[w * h];
    PixelGrabber pg = new PixelGrabber(img_surface, x, y, w, h, pixels, 0, w);
    try {
       pg.grabPixels();
    } catch (InterruptedException e) {
       System.err.println("interrupted waiting for pixels!");
       return;
    }

    if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
       System.err.println("image fetch aborted or errored");
       return;
    }

    int alpha ;
    int red  ;
    int green;
    int blue ;
    int pixel = 0;

    for (int j = 0; j < h; j++) {
       for (int i = 0; i < w; i++) {
           pixel = pixels[j*w+i];
           alpha = (pixel >> 24) & 0xff;
           red   = (pixel >> 16) & 0xff;
           green = (pixel >>  8) & 0xff;
           blue  = (pixel      ) & 0xff;

/*           red = red / 4;
           green = green / 4;
           blue = blue / 4;
*/
           pixels[j*w+i] = (alpha << 24) + (red << 16) + (green << 8) + (blue);

       }
    }
    
    img_shadow[0] = createImage(new MemoryImageSource(w, h, ColorModel.getRGBdefault(), pixels, 0, w));
    }
    g.drawImage (img_shadow[0], x, y, w, h, appletThis);
 }

/* public void run() {

    animationMode = false;
    // animationThread = Thread.currentThread(); // Das Applet als ThreadInstanz einsetzen
    animationThread.setPriority (Thread.MIN_PRIORITY);

    while (animationThread != null) {
 
        try {
           if (animationMode) {
              animationStep++;
              if (animationStep<animationGraph.animationSteps()) {
                 animationGraph.setAnimationStep (animationStep);
                 System.out.println ("STEP"+animationStep);
              } else {
                 animationMode = false;
              }

              repaint();
              Thread.sleep(500);
           }
        } catch (InterruptedException e) {    
           System.out.println ("Unerwartete Unterbrechung");
        }          
     }

  
 }

 public void stop() {

    animationThread.stop();

 }
   */

 /** Die Initialisierungsmethode -> plaziert UI-Elemente */
 public void init() {

   // Pointer auf Draw selbst für DrawCanvas
    appletThis = this; // Dummy
    
   // Paint-Database-Klasse von Fabian
    Paint = new TPaint();
    Paint.PaintSettings().maxX = 399;   Paint.PaintSettings().maxY = 315; // Größe der Zeichenfläche
    Paint.PaintSettings().mapStartX = 0;   Paint.PaintSettings().mapStartY = 0; // Linker oberer, sichtbarer Punkt
    Paint.PaintSettings().Xratio = 1;   Paint.PaintSettings().Yratio = 1; // ZOOM = 100% 
    Paint.PaintSettings().setMarkerColor( new Color (0, 0, 190) );
    Paint.PaintSettings().setToleranz ( 4 );

   // Bitmap-Arrays besetzen
    img_toolpixhigh = new Image[17];
    img_toolpixpressed = new Image[17];
    img_toolpixhighpressed = new Image[17];
    img_shadow = new Image[6]; // 6 Bilder für die Shadows unserer Toolbars
    int curPix = 0;

   // Grafiken und MediaTracker initialisieren
    if (ApplicationMode) {
       img_stringbar = Toolkit.getDefaultToolkit().getImage("stringbox.gif");
       img_toolbar = Toolkit.getDefaultToolkit().getImage("toolbox.gif"); 
       img_hamster = Toolkit.getDefaultToolkit().getImage("hamster.gif");
       img_laufhamster = Toolkit.getDefaultToolkit().getImage("hamster3.gif");

       img_toolpixhigh[0] = Toolkit.getDefaultToolkit().getImage("point2.gif");
       img_toolpixhigh[1] = Toolkit.getDefaultToolkit().getImage("lupe2.gif");
       img_toolpixhigh[2] = Toolkit.getDefaultToolkit().getImage("erase2.gif");
       img_toolpixhigh[3] = Toolkit.getDefaultToolkit().getImage("new2.gif");
       img_toolpixhigh[4] = Toolkit.getDefaultToolkit().getImage("load2.gif");
       img_toolpixhigh[5] = Toolkit.getDefaultToolkit().getImage("save2.gif");
       img_toolpixhigh[6] = Toolkit.getDefaultToolkit().getImage("line2.gif");
       img_toolpixhigh[7] = Toolkit.getDefaultToolkit().getImage("rect2.gif");
       img_toolpixhigh[8] = Toolkit.getDefaultToolkit().getImage("circ2.gif");
       img_toolpixhigh[9] = Toolkit.getDefaultToolkit().getImage("filled2.gif");
       img_toolpixhigh[10] = Toolkit.getDefaultToolkit().getImage("colbox2.gif");
       img_toolpixhigh[11] = Toolkit.getDefaultToolkit().getImage("textbox2.gif");
       img_toolpixhigh[12] = Toolkit.getDefaultToolkit().getImage("editbox2.gif");
       img_toolpixhigh[13] = Toolkit.getDefaultToolkit().getImage("reorg2.gif");
       img_toolpixhigh[14] = Toolkit.getDefaultToolkit().getImage("connect2.gif");
       img_toolpixhigh[15] = Toolkit.getDefaultToolkit().getImage("kirsche2.gif");
       img_toolpixhigh[16] = Toolkit.getDefaultToolkit().getImage("globus2.gif");

       img_toolpixpressed[0] = Toolkit.getDefaultToolkit().getImage("point5.gif");
       img_toolpixpressed[1] = Toolkit.getDefaultToolkit().getImage("lupe5.gif");
       img_toolpixpressed[2] = Toolkit.getDefaultToolkit().getImage("erase5.gif");
       img_toolpixpressed[3] = Toolkit.getDefaultToolkit().getImage("new5.gif");
       img_toolpixpressed[4] = Toolkit.getDefaultToolkit().getImage("load5.gif");
       img_toolpixpressed[5] = Toolkit.getDefaultToolkit().getImage("save5.gif");
       img_toolpixpressed[6] = Toolkit.getDefaultToolkit().getImage("line5.gif");
       img_toolpixpressed[7] = Toolkit.getDefaultToolkit().getImage("rect5.gif");
       img_toolpixpressed[8] = Toolkit.getDefaultToolkit().getImage("circ5.gif");
       img_toolpixpressed[9] = Toolkit.getDefaultToolkit().getImage("filled5.gif");
       img_toolpixpressed[14] = Toolkit.getDefaultToolkit().getImage("connect5.gif");

       img_toolpixhighpressed[0] = Toolkit.getDefaultToolkit().getImage("point3.gif");
       img_toolpixhighpressed[1] = Toolkit.getDefaultToolkit().getImage("lupe3.gif");
       img_toolpixhighpressed[6] = Toolkit.getDefaultToolkit().getImage("line3.gif");
       img_toolpixhighpressed[7] = Toolkit.getDefaultToolkit().getImage("rect3.gif");
       img_toolpixhighpressed[8] = Toolkit.getDefaultToolkit().getImage("circ3.gif");
       img_toolpixhighpressed[9] = Toolkit.getDefaultToolkit().getImage("filled3.gif");
       img_toolpixhighpressed[14] = Toolkit.getDefaultToolkit().getImage("connect3.gif");

       img_stylebar = Toolkit.getDefaultToolkit().getImage("stylebox.gif");

       img_colorpanel = Toolkit.getDefaultToolkit().getImage("panel1.gif");

       img_map = Toolkit.getDefaultToolkit().getImage("karte1.gif");
    } else {
       img_stringbar = getImage (getCodeBase(), "stringbox.gif");
       img_toolbar = getImage (getCodeBase(), "toolbox2.gif");
       img_hamster = getImage (getCodeBase(), "hamster.gif"); 
       img_laufhamster = getImage (getCodeBase(), "hamster3.gif");

       img_toolpixhigh[0] = getImage (getCodeBase(), "point2.gif");
       img_toolpixhigh[1] = getImage (getCodeBase(), "lupe2.gif");
       img_toolpixhigh[2] = getImage (getCodeBase(), "erase2.gif");
       img_toolpixhigh[3] = getImage (getCodeBase(), "new2.gif");
       img_toolpixhigh[4] = getImage (getCodeBase(), "load4.gif");
       img_toolpixhigh[5] = getImage (getCodeBase(), "save4.gif");
       img_toolpixhigh[6] = getImage (getCodeBase(), "line2.gif");
       img_toolpixhigh[7] = getImage (getCodeBase(), "rect2.gif");
       img_toolpixhigh[8] = getImage (getCodeBase(), "circ2.gif");
       img_toolpixhigh[9] = getImage (getCodeBase(), "filled2.gif");
       img_toolpixhigh[10] = getImage (getCodeBase(), "colbox2.gif");
       img_toolpixhigh[11] = getImage (getCodeBase(), "textbox2.gif");
       img_toolpixhigh[12] = getImage (getCodeBase(), "editbox2.gif");
       img_toolpixhigh[13] = getImage (getCodeBase(), "reorg2.gif");
       img_toolpixhigh[14] = getImage (getCodeBase(), "connect2.gif");
       img_toolpixhigh[15] = getImage (getCodeBase(), "kirsche2.gif");
       img_toolpixhigh[16] = getImage (getCodeBase(), "globus2.gif");

       img_toolpixpressed[0] = getImage (getCodeBase(), "point5.gif");
       img_toolpixpressed[1] = getImage (getCodeBase(), "lupe5.gif");
       img_toolpixpressed[2] = getImage (getCodeBase(), "erase5.gif");
       img_toolpixpressed[3] = getImage (getCodeBase(), "new5.gif");
       img_toolpixpressed[4] = null;
       img_toolpixpressed[5] = null;
       img_toolpixpressed[6] = getImage (getCodeBase(), "line5.gif");
       img_toolpixpressed[7] = getImage (getCodeBase(), "rect5.gif");
       img_toolpixpressed[8] = getImage (getCodeBase(), "circ5.gif");
       img_toolpixpressed[9] = getImage (getCodeBase(), "filled5.gif");
       img_toolpixpressed[14] = getImage (getCodeBase(), "connect5.gif");

       img_toolpixhighpressed[0] = getImage (getCodeBase(), "point3.gif");
       img_toolpixhighpressed[1] = getImage (getCodeBase(), "lupe3.gif");
       img_toolpixhighpressed[2] = null;  img_toolpixhighpressed[3] = null;
       img_toolpixhighpressed[4] = null;  img_toolpixhighpressed[5] = null;
       img_toolpixhighpressed[6] = getImage (getCodeBase(), "line3.gif");
       img_toolpixhighpressed[7] = getImage (getCodeBase(), "rect3.gif");
       img_toolpixhighpressed[8] = getImage (getCodeBase(), "circ3.gif");
       img_toolpixhighpressed[9] = getImage (getCodeBase(), "filled3.gif");
       img_toolpixhighpressed[14] = getImage (getCodeBase(), "connect3.gif");

       img_stylebar = getImage (getCodeBase(), "stylebox.gif");
       img_colorpanel = getImage (getCodeBase(), "panel1.gif");
       img_map = getImage (getCodeBase(), "karte1.gif");
      
       dMediaTracker = new MediaTracker (this);

           //       if (img_stringbar==null) { dMediaTracker.addImage (img_stringbar, 0); }

       if (img_toolbar!=null) { dMediaTracker.addImage (img_toolbar, 0); }
       for (curPix = 0; curPix < 17; curPix++) {
          if (img_toolpixhigh[curPix]!=null) { dMediaTracker.addImage (img_toolbar, 1+curPix); } // 1 - 17
          if (img_toolpixpressed[curPix]!=null) { dMediaTracker.addImage (img_toolbar, 50+curPix); } // 51 - 67
       }

       try {
          for (curPix = 0; curPix < 17; curPix++) {
             if (img_toolpixhigh[curPix]!=null) { dMediaTracker.waitForID (1+curPix); } // 1 - 17
             if (img_toolpixpressed[curPix]!=null) { dMediaTracker.waitForID (51+curPix); } // 51 - 67
          }
          /* dMediaTracker.waitForID (0);   dMediaTracker.waitForID (1);    dMediaTracker.waitForID (2);
          dMediaTracker.waitForID (3);   dMediaTracker.waitForID (4);    dMediaTracker.waitForID (5);
          dMediaTracker.waitForID (6);   dMediaTracker.waitForID (7);    dMediaTracker.waitForID (8);
          dMediaTracker.waitForID (9);   dMediaTracker.waitForID (10);
					 dMediaTracker.waitForID (11);   dMediaTracker.waitForID (12);
          dMediaTracker.waitForID (13);  dMediaTracker.waitForID (14);
                                         dMediaTracker.waitForID (17);   dMediaTracker.waitForID (18);
          dMediaTracker.waitForID (19);  dMediaTracker.waitForID (20); */
       } catch (InterruptedException ex) {
          System.out.println ( "Konnte Grafik nicht laden ("+ex.toString()+")" ); 
       } 

      // Zeichenfläche für Flickerreduktion setzen
       dSize = getSize();
       img_surface = createImage (dSize.width, dSize.height); // gfx-Buffering
       g_surface = img_surface.getGraphics ();
    }

   // Koordinaten der Bars setzen
    rect_toolbar = new TRect (460, 20, 85, 100);
    rect_innertoolbar = new TRect (465, 40, 75, 75);
    rect_stylebar = new TRect (440, 145, 119, 50);
    rect_innerstylebar = new TRect (445, 165, 109, 25);
    rect_stringbar = new TRect (460, 215, 85, 75);
    rect_innerstringbar = new TRect (465, 235, 75, 50);

   // Farben zuweisen
    Paint.PaintSettings().currentBGColor = Color.white;
    Paint.PaintSettings().currentColor = Color.black;
    color_set = new Color[13];
    color_set[0] = Color.black;  color_set[1] = Color.blue;  color_set[2] = Color.cyan;
    color_set[3] = Color.darkGray;  color_set[4] = Color.gray;  color_set[5] = Color.green;
    color_set[6] = Color.lightGray;  color_set[7] = Color.magenta;  color_set[8] = Color.orange;
    color_set[9] = Color.pink;  color_set[10] = Color.red;  color_set[11] = Color.white;
    color_set[12] = Color.yellow;  

   // Hintergrundfarbe setzen 
    setBackground (Paint.PaintSettings().currentBGColor);

   // Bild (Hamster) für Lauf des Handlungsreisenden setzen
    Paint.PaintSettings().setTSPimage (img_laufhamster);

   // Event-Handling anschalten
    addMouseListener(unserMouseListener); // Mouse-Event-Handling aktiv.
    addMouseMotionListener(unserMotionListener); 
    addKeyListener(unserKeyListener); 

   // Thread für die saubere Animation initen
     //    animationThread = new Thread (this);
     //    animationThread.start();
 }  

 /** Die Main-Methode des JavaMalprogramms
   * @param String[] Die (nicht ausgewerteten) Kommandozeilenparameter
   */
 public static void main (String Args[]) {

   // Action-Listener für Exit-Event definieren
    WindowListener ExitListener = new WindowAdapter()
    {
      // Event-Methode die beim Schließen aufgerufen wird
       public void windowClosing (WindowEvent ThisEvent) {
          System.exit (0); // Errorlevel 0 zurück
       }
    };

   // Frame anlegen und die applet-Klasse einpflanzen    
    Frame AppletFrame = new Frame("Das JavaMalprogramm");
    AppletFrame.setSize (400,400);
    AppletFrame.addWindowListener(ExitListener); // Event-Handling aktiv.

   // Neue Instanz von uns selbst erzeugen
    Draw thisDraw = new Draw(); 
    thisDraw.setApplicationMode (true, AppletFrame);
    AppletFrame.add(thisDraw); // pflanze applet ein...

   // Initialisieren des Applets
    thisDraw.init();
    thisDraw.start();

    AppletFrame.setSize (600,400);
    // AppletFrame.pack();
    // AppletFrame.setSize(AppletFrame.getPreferredSize());
    AppletFrame.show(); // und anzeigen (visible=true)...
 }

}

// Die Klasse TRect enthält links, rechts und height, width - Variablen
class TRect {

  public int x, y;
  public int width, height;  

  public TRect () {
     x = 0;  y = 0;  width = 0;  height = 0;
  }  

  public TRect (int a1, int a2, int a3, int a4) {
     x = a1;  y = a2;  width = a3;  height = a4;
  }

  // Prüft, ob ax|ay in dem TRect enthalten ist
  public boolean IsIn (int ax, int ay) {
     if ((ax >= x) && (ax < x+width) && (ay >= y) && (ay < y+height)) {
        return (true);
     } else {
        return (false); 
     } 
  }

}
