Javafx 2.0에서 Draggable Node를 만드는 방법. 자바 FX가 GUI의 목적을 위해 특별히입니다 만 나는 일부 샘플 감사Javafx 2.0에서 드래그 가능한 노드를 만드는 방법.
2
A
답변
10
오라클은 tutorial on draggable nodes를 제공해야합니다. 때로는
private Node makeDraggable(final Node node) {
final DragContext dragContext = new DragContext();
final Group wrapGroup = new Group(node);
wrapGroup.addEventFilter(
MouseEvent.ANY,
new EventHandler<MouseEvent>() {
public void handle(final MouseEvent mouseEvent) {
if (dragModeActiveProperty.get()) {
// disable mouse events for all children
mouseEvent.consume();
}
}
});
wrapGroup.addEventFilter(
MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
public void handle(final MouseEvent mouseEvent) {
if (dragModeActiveProperty.get()) {
// remember initial mouse cursor coordinates
// and node position
dragContext.mouseAnchorX = mouseEvent.getX();
dragContext.mouseAnchorY = mouseEvent.getY();
dragContext.initialTranslateX =
node.getTranslateX();
dragContext.initialTranslateY =
node.getTranslateY();
}
}
});
wrapGroup.addEventFilter(
MouseEvent.MOUSE_DRAGGED,
new EventHandler<MouseEvent>() {
public void handle(final MouseEvent mouseEvent) {
if (dragModeActiveProperty.get()) {
// shift node from its initial position by delta
// calculated from mouse cursor movement
node.setTranslateX(
dragContext.initialTranslateX
+ mouseEvent.getX()
- dragContext.mouseAnchorX);
node.setTranslateY(
dragContext.initialTranslateY
+ mouseEvent.getY()
- dragContext.mouseAnchorY);
}
}
});
return wrapGroup;
}
당신이 필터 드래그 문맥을 필요로하지 않으며, 단지이 example에 같은 다양한 마우스 이벤트에 작용하여 간단한 일을 수행 할 수 있습니다 :
을 여기 튜토리얼에서makeDraggable
방법
static class Delta { double x, y; }
// make a node movable by dragging it around with the mouse.
private void enableDrag(final Circle circle) {
final Delta dragDelta = new Delta();
circle.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = circle.getCenterX() - mouseEvent.getX();
dragDelta.y = circle.getCenterY() - mouseEvent.getY();
circle.getScene().setCursor(Cursor.MOVE);
}
});
circle.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
circle.getScene().setCursor(Cursor.HAND);
}
});
circle.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
circle.setCenterX(mouseEvent.getX() + dragDelta.x);
circle.setCenterY(mouseEvent.getY() + dragDelta.y);
}
});
circle.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
circle.getScene().setCursor(Cursor.HAND);
}
}
});
circle.setOnMouseExited(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
circle.getScene().setCursor(Cursor.DEFAULT);
}
}
});
}
주변 노드를 드래그하는 동일한 기술은 drag around stages로 사용할 수 있습니다
static class Delta { double x, y; }
/** makes a stage draggable using a given node */
public static void makeDraggable(final Stage stage, final Node byNode) {
final Delta dragDelta = new Delta();
byNode.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = stage.getX() - mouseEvent.getScreenX();
dragDelta.y = stage.getY() - mouseEvent.getScreenY();
byNode.setCursor(Cursor.MOVE);
}
});
byNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
byNode.setCursor(Cursor.HAND);
}
});
byNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
stage.setX(mouseEvent.getScreenX() + dragDelta.x);
stage.setY(mouseEvent.getScreenY() + dragDelta.y);
}
});
byNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.HAND);
}
}
});
byNode.setOnMouseExited(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.DEFAULT);
}
}
});
}
부모 노드 (여러 자식 노드가 포함되어 있음) 주위를 끌기위한 샘플입니다. 이 예는 대부분의 노드가 가지고 있지 않은 centerX/Y 속성에 의존하지 않으므로 위에 나온 원 기반 예제보다 일반적입니다. 대신 parentX 또는 Y에있는 모든 노드에서 사용할 수있는 layoutX/Y에서 작동합니다 .
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.scene.text.TextBoundsType;
import javafx.stage.Stage;
public class TextOnCircleWithDragging extends Application {
private static final int W = 400;
private static final int H = 400;
private static final int R = 15;
@Override
public void start(Stage stage) {
final StackPane circleWithText = new StackPane(
createCircle(),
createText()
);
circleWithText.relocate(
W/2 - R/2,
H/2 - R/2
);
makeDraggable(circleWithText);
stage.setScene(
new Scene(
new Pane(circleWithText),
W, H
)
);
stage.show();
}
private Circle createCircle() {
final Circle circle = new Circle(R);
circle.setFill(Color.PALEGREEN);
circle.relocate(0, 0);
return circle;
}
private Text createText() {
final Text text = new Text("A");
text.setBoundsType(TextBoundsType.VISUAL);
return text;
}
private void makeDraggable(Node node) {
final Delta dragDelta = new Delta();
node.setOnMouseEntered(me -> {
if (!me.isPrimaryButtonDown()) {
node.getScene().setCursor(Cursor.HAND);
}
});
node.setOnMouseExited(me -> {
if (!me.isPrimaryButtonDown()) {
node.getScene().setCursor(Cursor.DEFAULT);
}
});
node.setOnMousePressed(me -> {
if (me.isPrimaryButtonDown()) {
node.getScene().setCursor(Cursor.DEFAULT);
}
dragDelta.x = me.getX();
dragDelta.y = me.getY();
node.getScene().setCursor(Cursor.MOVE);
});
node.setOnMouseReleased(me -> {
if (!me.isPrimaryButtonDown()) {
node.getScene().setCursor(Cursor.DEFAULT);
}
});
node.setOnMouseDragged(me -> {
node.setLayoutX(node.getLayoutX() + me.getX() - dragDelta.x);
node.setLayoutY(node.getLayoutY() + me.getY() - dragDelta.y);
});
}
public static void main(String[] args) {
launch(args);
}
private class Delta {
public double x;
public double y;
}
}
지연 조정
커서 뒤에 끌고 노드 지연을보고하고 해결하고자하는 경우, 다음에 Xanatos의 답변을 참조하십시오
그는 다음과 같이 설정할 것을 제안합니다 :
-Dprism.vsync=false
0
파티에 조금 늦게,하지만 난 노드의 많은 subclassses에 draggability 필요, 그래서 유틸리티 클래스의 사용 생성 : 이것은 모든 노드에 적용 할 수
/**
* Generalised implementation of 'Draggability' of a {@link Node}. The Draggable class is used as a 'namespace' for the internal
* class/interfaces/enum.
* @author phill
*
*/
public class Draggable {
public enum Event {
None, DragStart, Drag, DragEnd
}
/**
* Marker for an entity that has draggable nature.
* @author phill
*/
public interface Interface {
public abstract Draggable.Nature getDraggableNature();
}
public interface Listener {
public void accept(Nature draggableNature, Event dragEvent);
}
/**
* Class that encapsulates the draggable nature of a node.
* <ul>
* <li>EventNode: the event that receives the drag events</li>
* <li>One or more DragNodes: that move in response to the drag events. The EventNode is usually (but not always) a
* DragNode</li>
* <li>Listeners: listen for the drag events</li>
* </ul>
* @author phill
*
*/
public static final class Nature implements EventHandler<MouseEvent> {
private double lastMouseX = 0, lastMouseY = 0; // scene coords
private boolean dragging = false;
private final boolean enabled = true;
private final Node eventNode;
private final List<Node> dragNodes = new ArrayList<>();
private final List<Listener> dragListeners = new ArrayList<>();
public Nature(final Node node) {
this(node, node);
}
public Nature(final Node eventNode, final Node... dragNodes) {
this.eventNode = eventNode;
this.dragNodes.addAll(Arrays.asList(dragNodes));
this.eventNode.addEventHandler(MouseEvent.ANY, this);
}
public final boolean addDraggedNode(final Node node) {
if (!this.dragNodes.contains(node)) {
return this.dragNodes.add(node);
}
return false;
}
public final boolean addListener(final Listener listener) {
return this.dragListeners.add(listener);
}
public final void detatch() {
this.eventNode.removeEventFilter(MouseEvent.ANY, this);
}
public final List<Node> getDragNodes() {
return new ArrayList<>(this.dragNodes);
}
public final Node getEventNode() {
return this.eventNode;
}
@Override
public final void handle(final MouseEvent event) {
if (MouseEvent.MOUSE_PRESSED == event.getEventType()) {
if (this.enabled && this.eventNode.contains(event.getX(), event.getY())) {
this.lastMouseX = event.getSceneX();
this.lastMouseY = event.getSceneY();
event.consume();
}
} else if (MouseEvent.MOUSE_DRAGGED == event.getEventType()) {
if (!this.dragging) {
this.dragging = true;
for (final Listener listener : this.dragListeners) {
listener.accept(this, Draggable.Event.DragStart);
}
}
if (this.dragging) {
final double deltaX = event.getSceneX() - this.lastMouseX;
final double deltaY = event.getSceneY() - this.lastMouseY;
for (final Node dragNode : this.dragNodes) {
final double initialTranslateX = dragNode.getTranslateX();
final double initialTranslateY = dragNode.getTranslateY();
dragNode.setTranslateX(initialTranslateX + deltaX);
dragNode.setTranslateY(initialTranslateY + deltaY);
}
this.lastMouseX = event.getSceneX();
this.lastMouseY = event.getSceneY();
event.consume();
for (final Listener listener : this.dragListeners) {
listener.accept(this, Draggable.Event.Drag);
}
}
} else if (MouseEvent.MOUSE_RELEASED == event.getEventType()) {
if (this.dragging) {
event.consume();
this.dragging = false;
for (final Listener listener : this.dragListeners) {
listener.accept(this, Draggable.Event.DragEnd);
}
}
}
}
public final boolean removeDraggedNode(final Node node) {
return this.dragNodes.remove(node);
}
public final boolean removeListener(final Listener listener) {
return this.dragListeners.remove(listener);
}
/**
* When the initial mousePressed is missing we can supply the first coordinates programmatically.
* @param lastMouseX
* @param lastMouseY
*/
public final void setLastMouse(final double lastMouseX, final double lastMouseY) {
this.lastMouseX = lastMouseX;
this.lastMouseY = lastMouseY;
}
}
}
을 :
final Rectangle rectangle = new Rectangle(100, 100, 200, 50);
Draggable.Nature nature = new Draggable.Nature(rectangle);
그리고 사각형은 드래그 가능합니다. Draggable.Nature에 리스너를 추가 할 수 있으며 동시에 드래그 할 수있는 추가 노드를 추가 할 수 있습니다.
이것은 나의 필요를 해결했습니다. 도움이되기를 바랍니다.
관련 문제
- 1. JavaFX 트리 하위 노드를 만드는 방법
- 2. JavaFX 2.0에서 기하학적 도형을 만드는 방법은 무엇입니까?
- 3. GWT dnd에서 드래그 가능한 위젯을 만드는 방법
- 4. 드래그 가능한 노드를 다른 레이어로 이동
- 5. javafx, 드래그 최적화 - 다양한 아이디어
- 6. JavaFX Treeview - "두"그래픽이있는 부모 노드를 만드는 방법
- 7. 드래그 가능한 항목을 변경하거나 드래그 가능한 데이터를 올바르게 제거하는 방법
- 8. JavaFX - 노드 주위에 클릭 가능한 영역을 만드는 방법
- 9. div에서 드래그 가능한 이미지를 만드는 방법은 무엇입니까?
- 10. matplotlib에서 드래그 가능한 범례를 만드는 방법은 무엇입니까?
- 11. 드래그 가능한 항목으로 ListView를 만드는 방법은 무엇입니까?
- 12. JavaFX : 두 노드를 한 줄씩 연결하는 방법?
- 13. JavaFX 8에서 크기 조정 가능한 드래그 가능 창 만들기
- 14. GWT에서 드래그 가능한 팝업?
- 15. 제스처를 통해 드래그 가능한 경로에서 특정 지점을 만드는 방법. iPhone
- 16. 알림 패널과 같이 iPhone에서 드래그 가능한 패널을 만드는 방법
- 17. jQuery에서 전체 드래그 가능한 웹 사이트를 만드는 방법
- 18. JQuery UI : 드래그 가능한 요소가 투명합니다. 그것을 만드는 방법?
- 19. 화면에서 윈도우처럼 드래그 가능한 사용자 정의 컨트롤을 만드는 방법
- 20. 자바 스크립트 - 여러 개의 드래그 가능한 클론을 만드는 방법?
- 21. drappable으로 드래그 가능한 스냅을 만드는 방법, 스와핑을 허용 하시겠습니까?
- 22. JavaFX에서 드래그 가능한 요소의 CSS
- 23. 드래그 가능한 드래그 취소 취소
- 24. 드래그 가능한 구성 요소?
- 25. JavaFX : 밑에있는 노드를 액세스 가능하게 만드는 방법은 무엇입니까?
- 26. JavaFX 가상 키보드가 노드를 겹칩니다.
- 27. javafx - 노드를 동적으로 크기 조정
- 28. JavaFX 2.0에서 캐럿 색상을 변경하는 방법은 무엇입니까?
- 29. JavaFX 2.0에서 TableView의 다중 선택 읽기
- 30. JavaFX 2.0에서 NumberAxis의 값을 변경할 수 있습니까?