HTML 5 – Unterstützung des IE 9 Stand: 25. Februar 2011

Hier ein kurzer Post….

IE9 hängt dem HTML 5 Standard weit hinterher

Der Microsoft Internet Explorer 9 schneidet bei HTML5Test.com in seiner aktuellsten Beta-Version immer noch schlechter ab, als ein Firefox, welcher bereits 1 Jahr alt ist. Chrome hat auch kräftig zugelegt. Ich habe die IE9 Beta gerade (25. Februar 2011) frisch runtergeladen und erhalte folgendes niederschmetterndes Ergebnis:

Zum Vergleich ein Screenshot des Android Browsers auf dem Samsung Galaxy i9000 :

image

Wichtige Innovationen sollen nicht unterstützt werden

Da Microsoft eine ActiveX-Variante von Direct3D anbietet, besteht keine Intention für eine Implementierung der WebGL-API, die das darstellen von 3D-Objekten im Browser unterstützt. Sollte sich das auf weitere Releases auswirken ist WebGL eine Totgeburt, oder der Internet Explorer wird aussterben.

Es ist keine IndexedDB zur Speicherung von Offline-Inhalten geplant, Webworkers/Websockets sind nicht vorhanden.

SAP und JAVA: Zugriff auf Funktionsbausteine / BAPIs mit dem Java Connector

Aufgabenstellung

Es soll auf Daten aus dem SAP System zugegriffen werden, ohne die Datenbank direkt anzusprechen.

Ansatz

Durch die Verwendung des Java-Connectors (JCo) werden Funktionsbausteine / BAPIs als SAP Schnittstellen verwendet. Die Funktionsbausteine können über die SAP GUI mit dem BAPI-Explorer gesucht und mit der TA 37 getestet werden. Der nachfolgende Artikel beschäftigt sich mit dem Aufruf von einem Java-Server. Der JCo kann im Market Place von SAP kostenlos heruntergeladen werden.

Lösung

Remote Function Call (techn. RPC)

Ein Remote Function Call (RFC) ist die SAP-Implementierung von Remote Procedure Calls (RPC). Über einen RFC lassen sich Funktionsbausteine, bzw. BAPI’s aufrufen.

Ein RFC verwendet die Kommunikationsregeln des CPI-C-Protokolls, welches auf TCP/IP oder LU 6.2 basiert. LU 6.2 war dabei das Kommunikationsprotokoll von R/2-Mainframe-Systemen und wurde bei R/3 durch den einheitlichen TCP/IP-Standard ersetzt.

RFC’s nehmen ausschließlich Call-By-Value-Parameter entgegen, da die Übergabe von Zeigern und Speicheradressen hier keinen Sinn macht. In einem fremden System würde die Speicheradresse auf einen Speicher-Bereich zeigen, in dem keine oder Daten von anderen Anwendungen vorhanden sind.

Funktionsweise des Java Connectors (JCo)

Der Java Connector unterstützt den Aufruf von RFC’s, bzw. BAPIs aus einer externen Java-Umgebung (SAP-inbound-call), sowie den Aufruf externer JAVA-Funktionalitäten aus ABAP-Programmen heraus (SAP-outbound-call). Für die letztgenannte Variante existiert im Example-Verzeichnis des JCo ein Beispiel, in dem ein JCo-Server implementiert wird. Der JCo-Server muss dem SAP-System über die Transaktion SM59 bekanntgemacht werden.

Bei einem SAP-Inbound-Call ist die Vorgehensweise die folgende:

1.) Anmeldung der Java-Applikation am R/3-System

JCO.Client Conection = JCO.createClient(Mandant,
                                        Username,
                                        Password,
                                        Language,
                                        Hostname,
                                        Systemnummer);

Connection.connect();

2.) Herunterladen des Repository für den Funktionsbaustein

IRepository rep = JCO.createRepository("MyRepository", Connection);
IFunctionTemplate template = rep.getFunctionTemplate("BAPI_NAME");
JCO.Function funktion = new JCO.Function(template);

3.) Holen einer Referenz auf die Übergabeparameter

JCO.ParameterList import = funktion.getImportParameterList();
JCO.ParameterList table = funktion.getTableParameterList();

4.) Befüllen des Bausteins

5.) Funktionsbaustein ausführen

Connection.execute(funktion);

6.) Hole Referenz auf Rückgabeparameter

JCO.ParameterList export = funktion.getExportParameterList();
JCO.ParameterList table = funktion.getTableParameterList();

7.) Auslesen des Bausteins

Es werden synchrone (sRFC), asynchrone (aRFC) und transaktionale Aufrufe (tRFC, qRFC), sowie Connection-Pooling unterstützt (auf JAVA- wie auf ABAP-Seite).

SAP lobt zwar die Plattformunabhängigkeit des Connectors, jedoch stößt man bei einfachem Kopieren des Bytecodes auf Probleme, da hier eine plattformabhängige Bibliotheksdatei gekapselt wird, die bei höheren Releases nicht mehr funktioniert. Unter Windows wird die Datei librfc32.dll und unter Linux die Datei librfccm.so gekapselt.

Durch die Kapselung der Datei ist es ohne weiteres möglich, Konnektoren für nicht unterstützte Programmiersprachen zu implementieren.

Ein Tutorial der Zeitschrift „Der Entwickler“, welches Online zur Verfügung steht, zeigt durch Verwendung dieser Bibliothek, wie man Delphi an SAP-Systeme andocken kann. Der Artikel trägt den Namen „Delphi goes SAP“. Da es für Delphi keine Konnektoren wie den Java Connector gibt, ist die Kapselung dieser Datei notwendig.

Parameter von Funktionsbausteinen

Da die meisten SAP-Anwendungen im ABAP-Stack implementiert worden, greift man mit dem JAVA Connector hauptsächlich auf remotefähige Funktionsbausteine zu. Diesen werden entweder ausgefüllte Tabellen, oder Import-Parameter zur Verarbeitung übergeben. Als Ausgabe liefert ein Funktionsbaustein Fehler-Parameter, Export-Parameter, neue Tabellen oder auch die übergebenen Tabellen mit neuen Werten zurück. Hierfür ist es notwendig den syntaktischen Aufbau von JCO-Syntax zu kennen.

Import-Parameter

Import-Parameter kann man sich wie einfache Übergabeparametern aus bekannten Programmiersprachen vorstellen. Ein Import-Parameter entspricht einem Feld, was einen Datentyp beinhaltet (Char, Integer, String, Double…). Es kann keine Array’s, Listen oder Tabellen entgegennehmen.

SAP kennzeichnet hauseigene Funktionsbausteine mit einem vorangehenden I für „Import“. Mit der Transaktion SE16 ist es möglich sich die notwendigen Import-Parameter anzusehen.

Nicht alle Import-Parameter sind erforderlich, es gibt auch optionale Parameter. Nicht jeder Funktionsbaustein hat Import-Parameter.

Der nachstehende Code zeigt, wie mit Hilfe des JAVA Connectors der Funktionsbaustein „CFX_API_USER_GETDETAIL“, der die Detaildaten eines cFolders-Benutzers zurückgibt befüllt wird:

public String gibListeVonUsern()
{
  IRepository repository = JCO.createRepository("MYRepository", client);
  IFunctionTemplate ftemplate = repository
 .getFunctionTemplate("CFX_API_USER_GETDETAIL");
  Function func = ftemplate.getFunction();

  JCO.ParameterList input = func.getImportParameterList();
  input.setValue("KARPBJ01", "I_USER_ID");

  // Funktion aufrufen
  client.execute(func);
  (...)
}

Export-Parameter

Nachdem die Funktion ausgeführt wurde, kann über die Export-Parameter iteriert werden um die Rückgabewerte auszulesen. Dazu hat die Klasse ParameterList die Methode getFieldCount(), welche die Anzahl der Rückgabeparameter zurückliefert. Die Methode getString(index) ermöglich über den inkrementellen Index die Iteration mit einer Schleife. Dadurch lassen sich alle Parameter dynamisch auslesen.

Nachfolgend wird aus der aufgerufenden Funktion über die Export-Parameterliste iteriert und das Ergebnis an den String „informationen“ angehangen.


public String gibListeVonUsern()
{
  (...) //Hier war der Funktionsaufruf

  JCO.ParameterList output = func.getExportParameterList();

  for (int i = 0; i < output.getFieldCount(); i++)
  {
    informationen = informationen + output.getString(i) + "\n";
  }
  return informationen;
}

Changing-Parameter

Im Gegensatz zu Import- und Export-Parametern funktionieren Changing-Parameter in beide Richtungen (bidirektional). Der Aufruf ist dabei Call-By-Reference-ähnlich, da sich nach dem Ausführen des Funktionsbausteins mit dem Befehl client.execute(func); der Wert im Feld ändern kann. Das Befüllen und auslesen funktioniert dabei wie bei den Import- und Export-Parametern.

Table-Parameter

Table-Parameter sind bidirektional. Die Referenz auf eine Tabelle kann geholt werden, bevor die Funktion ausgeführt wurde. Hat man die Referenz auf die Tabelle, so lässt sich diese folgendermaßen befüllen:


  // Iteration über einen Vector
  for (int i = 0; i < vector.size(); i++)
  {
     // Neue Zeile an Tabelle anhängen und auf
     // neue Zeile wechseln
     table.appendRow();

     // schreibe in erste Spalte
     table.setValue((String)vector.get(i),0);

     // schreibe in zweite Spalte
     table.setValue((String)vector.get(i),1);
  }

Nachdem eine Funktion ausgeführt wurde, also nachdem Connection.execute(funktion); ausgeführt wurde, kann eine neue Tabelle zurückgeliefert werden, oder eine bereits befüllte Tabelle neue Werte beinhalten.

Um über eine Rückgabetabelle zu iterieren, gibt es die Funktion setRow(index). Das folgende Beispiel zeigt die Suche nach einem bestimmten String in der 3. Spalte und liefert das Feld „ID“ zurück:


  String rueckgabe = null;
  for (int i=0;i<outputtabelle.getNumRows();i++)
  {
    outputtabelle.setRow(i);

    if (outputtabelle.getString(2).equals(suche) )
    {
      rueckgabe = outputtabelle.getString("ID");
    }
  }

Wie ersichtlich wird, lässt sich die Spalte nicht nur anhand des inkrementellen Indexes ansprechen, sondern auch über den Spaltennamen.

In manchen Fällen ist es nötig eine eigene Tabelle zu erzeugen und diese an einen Funktionsbaustein zu übergeben. Zum Beispiel funktioniert die Zuweisung einer befüllten Ergebnistabelle an eine Übergabetabelle nicht, in diesem Fall muss man die Daten in einer Schleife einfach rauskopieren.

Eine eigene Tabellendefinition erzeugt man in diesem Fall so:


  JCO.MetaData smeta  = new JCO.MetaData("DIS");

  smeta.addInfo("DOKAR",  JCO.TYPE_STRING,  3,  0, 0);
  smeta.addInfo("DOKVR",  JCO.TYPE_STRING ,   2, 0, 0);
  smeta.addInfo("DOKTL",  JCO.TYPE_STRING ,   3, 0, 0);
  smeta.addInfo("DOKNR",  JCO.TYPE_STRING ,   3, 0, 0);

  JCO.Structure structure = new JCO.Structure(smeta); 
  JCO.Table table = new JCO.Table(structure);

Struktur-Parameter

Strukturen gehören zu den Tabellen-Typ-Parametern und sind Sonderfälle. Eine Struktur kann innerhalb einer Tabelle, in Import- oder Export-Parametern auftreten. Hierbei handelt es sich lediglich um eine weitere Aufteilung innerhalb eines einzigen Feldes.

Der folgende Code zeigt, wie eine Referenz auf eine Inputstruktur und auf einen normalen Import-Parameter geholt wird .


JCO.Structure struktur =
func.getImportParameterList().getStructure("SELECT_DOCUMENTDATA");
JCO.ParameterList inputdata = func.getImportParameterList();
struktur.setValue(art, "DOCUMENTTYPE");
inputdata.setValue("X", "GETCLASSIFICATION");
Output.execute(funktion);

Fortsetzung folgt …

Responsive Design / Layoutgestaltung für jede Bildschirmauflösung

Aufgabenstellung

Ein HTML-Layout soll sich automatisch an die Gegebenheiten des Endgerätes anpassen, egal ob mobiles Endgerät oder eine Großleinwand

Ansatz

Responsive Design funktioniert durch die Verwendung des @media-Tags von CSS. Das Layout richtet sich an der Bildschirmauflösung und der Orientierung des Endgerätes

Lösung

Aufbau der CSS-Datei:

@media (min-width: 950px) 
{
  /* Hohe Auflösung */
}

@media (min-width: 450px) and (max-width: 900px)
{
  /* Mittlere Auflösung */
}

@media (max-width: 450px) 
{
  /* Kleine Auflösung */ 
}

Quelle: www.mariofink.de

Workflow Patterns – Teil 1

Workflows

Was ist ein Workflow?

Grundsätzlich ist ein Workflow erstmal nichts technisches. Es geht hierbei meistens (so auch hier) um Formulare, die in einem Unternehmen mehrere Abteilungen und Stationen durchlaufen. Ob das Formular auf einem Papier oder in einer rechnergestützten Anwendung realisiert wurde, spielt dabei vorerst keine Rolle.

Mithilfe von Workflows können Personen gemeinsam an Dokumenten arbeiten. Organisationen können einheitliche Geschäftsprozesse einhalten und die Effizienz und Produktivität der Organisation verbessern, indem die Aufgaben und Schritte einzelner Geschäftsprozesse verwaltet und harmonisiert werden. Auf diese Weise können sich die Personen, die diese Aufgaben ausführen, auf die Arbeit selbst und nicht auf die Verwaltung des Workflows konzentrieren.

Papiergebundene Workflows haben im Vergleich zu rechnergestützten Workflows den Nachteil, dass sich die folgenden Fragen nicht beantworten lassen:

  • Wo befindet sich das Dokument?
  • Wer bearbeitet es?
  • Wer hat es schon bearbeitet?
  • Kann ich das Dokument schnell zurückholen?
  • Wann wurde es in Umlauf gebracht?
  • Wurde ein Datum überschritten?

Ein Workflow ist eine inhaltlich abgeschlossene, zeitlich und sachlogisch zusammenhängende Folge von Schritten, die zur Bearbeitung eines betriebswirtschaftlich relevanten Objektes notwendig sind und deren Funktionsübergänge von einem Informationssystem gesteuert werden.

Abgeschlossenheit: Ein Workflow definiert einen Arbeitsablauf mit einer Abfolge von Aktivitäten innerhalb einer Organisation. Die Abfolge beginnt an einem bestimmten Punkt und endet auch an einem solchem. Es gibt daher einen Initiator eines Workflows und eine Aktion, die am Ende definiert, was als nächstes passieren soll.

Zeitlicher Ablauf: Ein Workflow kann an einem Zeitpunkt 1 beginnen und an einem Zeitpunkt 5 aufhören. Wenn dies der Fall ist, existieren 5 Workflowpositionen.

Sachlogik:
Sachlogik dient dazu..

  • Aktionen zu validieren und Eingabefehler auszuschließen
  • den zeitlichen Ablauf anhand bestimmter Kriterien zu beeinflussen
  • Workflowpositionen nach Notwendigkeit wegfallen oder hinzukommen zu lassen
  • Schritte die automatisierbar sind durch definierte Logik durch den Workflow eigenständig erledigen zu lassen

In der Regel ist das betriebswirtschaftliche Objekt ein Formular, welches zum Einsammeln von Daten gedacht ist.

Wo werden Workflows verwendet und welchem Zweck dienen Sie?

Workflows werden überall dort verwendet, wo durch einen strukturierten Arbeitsablauf transparenz und Arbeitsersparnis erreicht werden kann. Arbeitsersparnis erhält man in der Regel durch den niedrigeren Koordinationsaufwand, die Transparenz hingegen durch die Möglichkeit den Status eines Workflows abzufragen (an welcher Workflowposition hängt es – wen muss ich ansprechen – wer ist verantwortlich?). Normalerweise würde man anfangen rumzutelefonieren, bei wem ein Dokument gerade liegt. Dies kann über eine Suchfunktion ínnerhalb des Informationssystems realisiert werden.

Wer braucht Workflows?

Personen, die …

  • … über Dokumente wie Formulare Informationen/Daten über mehrere, in der Organisation verteilte einsammeln und nicht die Zeit haben hinter einem Dokument hinterherzutelefonieren.
  • … den Verbleib eines Dokumentes genau nachvollziehen müssen
  • … nicht das Gesamt-Know-How eines Arbeitsprozesses besitzen und auf andere Personen angewiesen sind.
  • … einen Prozess mit erheblichem Aufwand optimieren möchten
  • … gerne mehr Zeit haben.

Welche Realisierungsmöglichkeiten gibt es für Worfklows?

  • Papiergebundene Workflows
  • Web-Workflows
  • Native Workflows
  • Systemintegrierte Workflow (z.B. SAP Workflow)

Wie plant man einen Workflow?

  • Entscheidung für die Implementierung eines Workflows
  • Anforderungserfassung
  • Definition von Zielen und des Optimierungspotentials
  • Festlegung der Workflowinfrastruktur
    • Präsentationsformen: Web/Windows/Mobil
    • Kommunikationstechniken für Beachrichtigungen: z.B. eMail: SMTP-Server, personifizierter Posteingang kombiniert mit eMail-Nachricht …
    • Benötigte Services/Dienste: Z.B. Bestände bei SAP abrufen…
  • Festlegung der Workflowtechnologie
    • Client-Server-Lösung
      • Web-Anwendung: Three-Tier-Architektur mit: Adobe Flex 3/FluorineFX/MS SQL Server
      • Mobil-Anwendung: Android App und iPhone App
    • Stand Alone Lösungen
      • Office Dokumente die sich per eMail versenden
  • Festlegung der Workflowarchitektur
    • Aufgaben, bzw. Rollen
      • Was für Tätigkeiten werden in dem Geschäftsprozess erledigt? Hier leiten sich die Rollen ab…
      • Eine Rolle ist eine Aufgabe, die eine Person in einem Unternehmen hat.
    • Ablauf
      • Reihenfolge: Welche Informationen müssen vor dem Erreichen einer Aufgabe/Workflowposition erfasst sein?

Workflow-Patterns

Workflow-Patterns sind bestimmte Entwurfsmuster, die in Workflow-Projekten immer wieder anzutreffen sind. Workflow-Patterns bestehen aus Workflow-Positionen und Workflow-Abläufen.

Workflow-Positionen

Eine Workflowposition dient der Vorlage, Bearbeitung und Bestätigung von Daten, die über ein Formular eingesammelt werden. Die Workflowposition kann einer Person, oder einer Gruppe von Personen zugeordnet sein.

Zeitliche Abfolgen

Zeitliche Abfolgen legen fest, wann eine Person das Dokument erhält und zu welchem Zeitpunkt.

Logische Abfolgen

Eine logische Abfolge wird nur dann abgearbeitet, wenn ein vorheriges Ereignis / eine vorherige Logikprüfung erfolgreich war und durch eine optionale Workflowpositionen durch die Abfolge erreicht wird.

Vorgänger- und Nachfolgerbeziehungen

Benötigt eine Person Daten von einer anderen, ist die Person, die die Daten benötigt, der Nachfolger der Person, die die Daten in das Formular eingibt. Es gibt hier also eine zeitliche Abhängigkeit, die durch Vorgänger- und Nachfolgebeziehungen defniert werden. Man versucht dabei so viele Positionen parallel abzuarbeiten, wie das möglich ist.

Workflow-Abläufe

Serialisierte Workflowabläufe

Einer nach dem anderen (bsp. Excel-Dokument das bei Bearbeitung immer gesperrt wird).
Vorteile:
* Klarer strukturierter Ablauf.
Nachteile:
* Es geht viel Zeit während der Bearbeitung verloren, wenn keine Daten vom Vorgänger benötigt werden (informelle Abhängigkeit zum Vorgänger).
* Keine parallele Abarbeitung möglich, da immer gesperrt.

Parallele Workflowabläufe

Es können mehrere Personen gleichzeitig an einer Workflowposition auf den Workflow zugfreifen. Erst wenn alle Personen bestätigt haben, läuft der Workflow weiter.

Fortsetzung folget (Workflow Patterns – Teil 2 inklusive Codebeispiele)

Adobe Flex 3: Event-Reihenfolge mit Methode testen

Problem

Adobe Flex 3 definiert eine Reihe von Standard-Events, die über die Kontext-Hilfe bei der Quellcodeingabe mit einem gelbem Blitz gekennzeichnet werden. Häufig nutzt man die Kontext-Hilfe im Flex-Builder (STRG+SPACE ruft sie beim Deklarieren/in der Deklaration eines MXML-Tags auf) um die definierten Events anzuzeigen.

Bei Event-Namen wie creationComplete, applicationComplete, InitializationComplete usw… stellt sich häuft die Frage nach der Reihenfolge

Ansatz

Es werden alle Events, die mit einem gelben Blitz versehen sind, an die deklarierte Methode „eventListener“ übergeben. Diese Methode listet im Debug-Modus über die TRACE-Funktion die Reihenfolge und das Auftreten der Events auf.

Lösung

<?xml version="1.0" encoding="utf-8"?>
<mx:Application added="eventListener(event)"
  addedToStage="eventListener(event)"
  applicationComplete="eventListener(event)"
  creationComplete="eventListener(event)"
  initialize="eventListener(event)"
  preinitialize="eventListener(event)"
  layout="absolute"
  xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:Script>
    <!&#91;CDATA&#91;
      import flash.utils.getQualifiedClassName;
      import mx.events.FlexEvent;
      
      private function eventListener(event:Event):void 
      {
         if (
              (event.target == this) || 
              (event.target == this.myDataGrid) ||
              (event.target == this.myPanel)
          ) 
         {
            trace(getQualifiedClassName(this) + ".eventListener: " +
	       getQualifiedClassName(event) + "." + event.type);
            trace("\ttarget: " + getQualifiedClassName(event.target));
          }
    }
 &#93;&#93;>
  </mx:Script>
  <mx:Panel added="eventListener(event)"
      addedToStage="eventListener(event)"
      creationComplete="eventListener(event)"
      id="myPanel"
      initialize="eventListener(event)"
      preinitialize="eventListener(event)">
  <mx:DataGrid  added="eventListener(event)"
           addedToStage="eventListener(event)"
           creationComplete="eventListener(event)"
           id="myDataGrid"
           initialize="eventListener(event)"
           preinitialize="eventListener(event)"/>
  </mx:Panel>
</mx:Application>

Microsoft SQL Server: Führende Nullen bei alphanumerischem String abschneiden

Problem

Ein String (z.B. eine Materialnummer oder eine Artikelnummer) besteht aus alphanumerischen Zeichen (z.B. 00003j422a3) und hat führende Nullen, welche abgeschnitten werden sollen (Ergebnis: 3j422a3). Siehe auch „Führende Nullen bei numerischen Strings abschneiden“.

Ansatz

* Zuerst werden ALLE Nullen durch Leerzeichen ersetzt
* danach werden alle Leerzeichen auf der linken Seite mit LTRIM abgeschnitten
* anschließend werden alle Leerzeichen durch 0en ersetzt.

Prämissen / Vorraussetzungen

Es sind keine Leerzeichen in dem String

Lösung

SELECT REPLACE(LTRIM(REPLACE(artikelnummer, '0', ' ')), ' ', '0') FROM dbo.cube1

Adobe Flex 3: Drag and Drop API

Aufgabenstellung

UI-Komponenten sollen per Drag and Drop verschoben werden können.

Ansatz

Dieser Artikel beschreibt die notwendigen Flex-APIs (DragManager) für die Implementierung einer Drag and Drop-Funktionalität am Beispiel der (siehe Nachfolgeartikel) eLearning-Anwendung für das V-Modell.

Lösung

1.) Definition der verschiebbaren Komponenten und der Behälter-Komponenten.

<!-- WIRD VERSCHOBEN -->
<mx:Button dragComplete="dragCompleteHandler(event);" 
label="System-Entwurf" id="btnSystementwurf"  />
<mx:Button dragComplete="dragCompleteHandler(event);" 
label="Software-Entwurf" id="btnSoftwareentwurf"  />
..

<!-- WIRD HINEINGESCHOBEN -->
<mx:HBox verticalAlign="middle" verticalScrollPolicy="off" 
horizontalScrollPolicy="off" id="dropField1" />
<mx:HBox verticalAlign="middle" verticalScrollPolicy="off" 
horizontalScrollPolicy="off" id="dropField2" />

2.) Registrierung der Eventlistener


<mx:Application creationComplete="{onCreationComplete()} ...

public function onCreationComplete():void
{
   // Registrierung des Buttons "Anforderungsanalyse" für das Verschieben in ein Feld
   this.btnAnforderungsnanalyse.addEventListener( MouseEvent.MOUSE_DOWN, beginDrag );

   // Registrierung des Buttons "AbnahmeEntwurf" für das Verschieben in ein Feld
   this.btnAbnahmeEntwurf.addEventListener( MouseEvent.MOUSE_DOWN, beginDrag );

...

   // Die DropListener werden an die UI-Komponten, bzw. die Komponeten, in die 
   // die Objekte geschoben werden können, angehängt
   this.dropField1.addEventListener( DragEvent.DRAG_ENTER, acceptDrop );
   this.dropField2.addEventListener( DragEvent.DRAG_ENTER, acceptDrop );
   ..
   this.dropField1.addEventListener( DragEvent.DRAG_DROP, handleDrop );
   this.dropField2.addEventListener( DragEvent.DRAG_DROP, handleDrop );
}
&#91;/actionscript3&#93;

3.) Implementierung der Logik - Hier: Überprüfung ob alles richtig verschoben ist
&#91;actionscript3&#93;
private function dragCompleteHandler(event:DragEvent):void {
     var draggedButton:Button = event.dragInitiator as Button;
     var dragInitCanvas:HBox = event.dragInitiator.parent as HBox;

     var stimmt1:Boolean = getButtons(dropField1).indexOf('btnAnforderungsnanalyse')>-1;
     var stimmt2:Boolean = getButtons(dropField2).indexOf('btnSystemarchitektur')>-1;
               	
     if(stimmt1&&stimmt2) 
     {
          Alert.show('Congratulations you did it!'); 
     }                	 
}  

4.) Welche Buttons sind in den Container? (Hier HBOX)

private function getButtons(box:HBox):String
{
var btnString:String=“;
var numChildren:Number = box.numChildren;

for (var i:int = 0; i < numChildren; i++) { if(box.getChildAt(i)["id"]) { btnString=box.getChildAt(i)["id"]; } } return btnString; } [/actionscript3] 5.) Management der Drag and Drop Funktionalität [actionscript3] public function beginDrag( mouseEvent:MouseEvent ):void { // the drag initiator is the object being dragged (target of the mouse event) var dragInitiator:IUIComponent = mouseEvent.currentTarget as IUIComponent; // the drag source contains data about what's being dragged var dragSource:DragSource = new DragSource(); // add some information to the drag source dragSource.addData( "name", dragInitiator.name ); dragSource.addData( "parent", dragInitiator.parent.name ); // ask the DragManger to begin the drag DragManager.doDrag( dragInitiator, dragSource, mouseEvent, null ); } public function handleDrop( dragEvent:DragEvent ):void { var dragInitiator:Button = Button( dragEvent.dragInitiator ); var dropTarget:HBox = dragEvent.currentTarget as HBox; HBox(dropTarget).addChild(dragInitiator); } public function acceptDrop( dragEvent:DragEvent ):void { var dropTarget:IUIComponent = dragEvent.currentTarget as IUIComponent; var dragSource:DragSource = dragEvent.dragSource; // accept the drop DragManager.acceptDragDrop( dropTarget ); // show feedback DragManager.showFeedback( DragManager.MOVE ); } [/actionscript3]