Graphics Nodes에 Drag-and-Drop Behavior 추가하기
JavaFX 소프트웨어는 여러분이 단지 몇줄의 코드만 가지고 그래픽 노드에 특정 행동을 쉽게 추가할수 있도록 해줍니다. 이 예제는 이미지에 dragging을 추가하는 두가지 방법을 보여줍니다.
코드 이해하기
드래그 가능한 형태를 만드는 가장 간단한 방법은 onMousePressed, 와 onMouseDragged 이벤트 핸들러를 오버라이드하는 것입니다. Figure 1의 코드는 두 이벤트 핸들러를 추가하기 위해서 ImageView를 상속받습니다. onMousePressed 핸들러는 translateX 와 translateY를 뺌으로서 이미지의 현재위치를 계산하여 조절된 마우스 클릭 위치를 저장합니다. onMouseDragged 이벤트에서 코드는 저장된 위치에 의해 수정된 마우스의 새로운 x 와 y를 이용하여 이미지의 위치를 이동시킵니다.
public class DraggableImage extends ImageView {
public-init var maxX = 200;
public-init var maxY = 200;
var startX = 0.0;
var startY = 0.0;
override var onMousePressed = function(e:MouseEvent):Void {
startX = e.sceneX-translateX;
startY = e.sceneY-translateY;
}
override var onMouseDragged = function(e:MouseEvent):Void {
var tx = e.sceneX-startX;
if(tx < 0) { tx = 0; }
if(tx > maxX-image.width) { tx = maxX-image.width; }
translateX = tx;
var ty = e.sceneY-startY;
if(ty < 0) { ty = 0; }
if(ty > maxY-image.height) { ty = maxY-image.height; }
translateY = ty;
}
}
Figure 1: DraggableImage.fx Class
이 새로운 DraggableImage를 사용하는 방법은 Figure 2에서 보여지는 것과 같이 원하는 크기의 인스턴스를 생성하고 그것을 여러분에 공간에 놓기만 하면 됩니다. 그 결과는 Figure 3의 애플릿처럼 보여져야 할것입니다.
Stage {
scene: Scene {
content: Group {
content: [
ImageView { image: Image { url: "{__DIR__}images/background.png" } },
DraggableImage {
maxX: 240
maxY: 320
image: Image { url: "{__DIR__}images/ball.png" }
}
]
}
}
}
Figure 2: Using DraggableImage
Figure 3: DraggableImage Applet
재사용이 가능한 Dragging
앞에 예제들은 정말로 잘 작동하지만 여러분이 드래그하고 싶은 각 모양을 상속받아야 합니다. 이러한 방법은 여러분이 드래그할수 있는 다수의 다른 모양들을 원할 때 제대로 동작하지 않을수 있습니다. 대신에 여러분은 Figure 4에서 보여지는 것처럼 어떠한 노드라도 dargging을 추가하는 재사용 가능한 DragBehavior 클래스를 생성할수 있습니다.
public class DragBehavior {
public var target: Node;
public-init var maxX = 200;
public-init var maxY = 200;
var startX = 0.0;
var startY = 0.0;
init {
target.onMousePressed = function(e:MouseEvent):Void {
startX = e.sceneX-target.translateX;
startY = e.sceneY-target.translateY;
}
target.onMouseDragged = function(e:MouseEvent):Void {
var tx = e.sceneX-startX;
if(tx < 0) { tx = 0; }
if(tx > maxX-target.boundsInLocal.width) { tx = maxX-target.boundsInLocal.width; }
target.translateX = tx;
var ty = e.sceneY-startY;
if(ty < 0) { ty = 0; }
if(ty > maxY-target.boundsInLocal.height) { ty = maxY-target.boundsInLocal.height; }
target.translateY = ty;
}
}
}
Figure 4: DragBehavior.fx Class
The DragBehavior 클래스는 앞서 Figure 2에서 본 예제와 같은 성능을 제공해 줍니다만 주어진 대상 Node가 어떠한 것이든 핸들러를 추가합니다. DragBehavior 클래스를 사용하기 위해서는 Figure 5에서 처럼 여러분이 움직이고 싶은 그래픽 오브젝트가 어느것이든 대상 Node로 정하기만 하면 됩니다. Figure 6의 애플릿에서 보여지는 것처럼 dragging 움직임은 같습니다.
var ball = ImageView {
image: Image { url: "{__DIR__}images/ball.png" }
};
var drag = DragBehavior { target: ball maxX: 240 maxY: 320 };
Stage {
scene: Scene {
content: [
ImageView { image: Image { url: "{__DIR__}images/background.png" } },
Group { content: ball },
]
}
}
Figure 5: Using DragBehavior Class
Figure 6: DragBehavior Applet
Josh Marinacci썬마이크로시스템즈의 엔지니어
