# Drag and Drop oder Alternative?



## whitebrazilian (18. Mai 2011)

Hallo,

ich möchte in meinem Java3D-Programm Kisten von einem Ort zu einem anderen befördern. Das könnte man ja einerseits mit Drag and Drop lösen, aber mit Hilfe der Klasse PickTranslateBehaviour lassen sich scheinbar nur Bewegungen in x- und y-Richtung realisieren. Zumindest bekomme ich es nicht hin die Kiste auch in z-Richtung zu verschieben. Da ich den Blickwinkel der Szene auch verändern kann, wirkt es auch komisch, dass sich die Kiste auf mich zubewegt, wenn ich die Maus nach links ziehe (weil sich der Blickwinkel eben nach links verändert hat).

Andererseits dachte ich mir, dass ich das Problem umgehen könnte, indem ich, nachdem ich eine Kiste "angewählt" habe, auf einen Ort klicken könnte und an diesem erscheint die Kiste dann.

Welche Möglichkeit ist denn einfacher zu implementieren? Ich habe leider schon öfter gehört, dass Drag and Drop sehr komplex werden kann und habe daher etwas Respekt davor.

Vielen Dank!

Mit freundlichen Grüßen,

Tobias Burger


----------



## Matthias K. (18. Mai 2011)

Hallo Tobias,
eine 3D-Bewegung mit der Maus zu realisieren ist meines Erachtens nicht möglich.
Ich würde an deiner Stelle die X- u. Y-Koordinaten der Maus, für die X- u. Y-Koordinaten
und z.B. zwei Pfeiltasten für die Veränderung
der Z-Koordinate der Kiste nutzen.

Gruß,
Matthias


----------



## whitebrazilian (24. Mai 2011)

Hallo Matthias,

danke für deine Antwort. Ich habe nun versucht ein Standard KeyBehavior zu implementieren, allerdings reagiert meine Box nicht.

Vielleicht spreche ich die Klasse auch falsch an...


```
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.util.*;

public class KeyBehavior extends Behavior {
private TransformGroup transformGroup;
private Transform3D trans=new Transform3D(),tempTrans=new Transform3D();
private WakeupCriterion criterion;

public KeyBehavior(TransformGroup tg){ transformGroup=tg;}

public void initialize(){
	
criterion=new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
wakeupOn(criterion);}

	public void processStimulus(Enumeration criteria) {
	WakeupOnAWTEvent ev;
	AWTEvent AWTEv[];
	KeyEvent KeyEv;
	
		while (criteria.hasMoreElements())
		{
			ev=(WakeupOnAWTEvent)criteria.nextElement();
			AWTEv=ev.getAWTEvent();
				for (int i=0; i<AWTEv.length; i++){
					
				 KeyEv=(KeyEvent)AWTEv[i];
				 transformGroup.getTransform(trans);
				 tempTrans.setIdentity();
				 	
				 	if (KeyEv.getKeyCode()==KeyEvent.VK_UP)
				 		
				 		tempTrans.setTranslation(new Vector3f(0f,0f,-0.2f));
				 	
				 	else if (KeyEv.getKeyCode()==KeyEvent.VK_DOWN)
				 		
				 		tempTrans.setTranslation(new Vector3f(0f,0f,0.2f));
		 
				 	else if (KeyEv.getKeyCode()==KeyEvent.VK_LEFT)
				 		
				 		tempTrans.rotY(Math.toRadians(2));
				 	
				 	else if (KeyEv.getKeyCode()==KeyEvent.VK_RIGHT)
				 		
				 		tempTrans.rotY(Math.toRadians(-2));
		 
				 	trans.mul(tempTrans);
				 	transformGroup.setTransform(trans);
				}
		 }
		
		 wakeupOn(criterion);
	}
}
```

Außerdem springt der CollisionDetector zu früh an, gibt mir also bereits weit vor Eintritt in ein anderes 3D-Objekt an, dass es sich darin befände. Beim Austritt wiederum sagt er mir zu spät, dass er sich außerhalb befindet.


```
class CollisionDetector extends Behavior {
	  /** The separate criteria used to wake up this behavior. */
	  protected WakeupCriterion[] theCriteria;

	  /** The OR of the separate criteria. */
	  protected WakeupOr oredCriteria;

	  /** The shape that is watched for collision. */
	  protected Box collidingShape;

	  /**
	   * @param box
	   *            Shape3D that is to be watched for collisions.
	   * @param theBounds
	   *            Bounds that define the active region for this behaviour
	   */
	  public CollisionDetector(Box box, Bounds theBounds) {
	    collidingShape = box;
	    setSchedulingBounds(theBounds);
	  }

	  /**
	   * This creates an entry, exit and movement collision criteria. These are
	   * then OR'ed together, and the wake up condition set to the result.
	   */
	  public void initialize() {
	    theCriteria = new WakeupCriterion[3];
	    theCriteria[0] = new WakeupOnCollisionEntry(collidingShape);
	    theCriteria[1] = new WakeupOnCollisionExit(collidingShape);
	    theCriteria[2] = new WakeupOnCollisionMovement(collidingShape);
	    oredCriteria = new WakeupOr(theCriteria);
	    wakeupOn(oredCriteria);
	  }

	  /**
	   * Where the work is done in this class. A message is printed out using the
	   * userData of the object collided with. The wake up condition is then set
	   * to the OR'ed criterion again.
	   */
	  public void processStimulus(Enumeration criteria) {
	    WakeupCriterion theCriterion = (WakeupCriterion) criteria.nextElement();
	    if (theCriterion instanceof WakeupOnCollisionEntry) {
	      Node theLeaf = ((WakeupOnCollisionEntry) theCriterion)
	          .getTriggeringPath().getObject();
	      System.out.println("Collided with " + theLeaf.getUserData());
	    } else if (theCriterion instanceof WakeupOnCollisionExit) {
	      Node theLeaf = ((WakeupOnCollisionExit) theCriterion)
	          .getTriggeringPath().getObject();
	      System.out.println("Stopped colliding with  "
	          + theLeaf.getUserData());
	    } else {
	      Node theLeaf = ((WakeupOnCollisionMovement) theCriterion)
	          .getTriggeringPath().getObject();
	      System.out.println("Moved whilst colliding with "
	          + theLeaf.getUserData());
	    }
	    wakeupOn(oredCriteria);  }
	}
```

Woran könnte das denn liegen?


----------



## whitebrazilian (24. Mai 2011)

Also die Sache mit dem KeyBahavior hab ich jetzt selbst gelöst, ich hatte vergessen die SchedulingBounds zu setzen. Gibt es eigentlich eine Möglichkeit, nicht die ViewPlatform zu drehen, sondern das Koordinatensystem?
Wenn ich nämlich meine große Box drehe, in die die Kisten sollen. Dann drücke ich weiterhin für die Z-Koordinate nach oben und unten. Allerdings "fährt" die Kiste dann nach links und rechts. Das ist ja nicht besonders intuitiv..


----------

