2016-10-26 5 views
1

2つのノード、1つの円と1つの長方形があります。どちらもドラッグアンドドロップ可能です。JavaFXで同時に2つのノードをドラッグ

これらを組み合わせる方法はありますか。そのため、ドラッグアンドドロップして両方を移動できますか? 私は既にグループを作成し、両方のノードを子として追加しようとしました(これは私にとってはうまくいきません)。次にコード例を示します。興味深い部分は、最下部のZoomAndScrollApplicationクラスです。それは、円と長方形(3つのラベル)それらのすべてがドラッグ可能ですが、私は(私はそれらのいずれかをクリックして、それらの両方をドラッグすることができていること)四角形、円を接続したいを作成します。

import javafx.application.Application; 
import javafx.beans.property.DoubleProperty; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.event.EventHandler; 
import javafx.scene.Group; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.control.Label; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.input.ScrollEvent; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

class PannableCanvas extends Pane { 

    DoubleProperty myScale = new SimpleDoubleProperty(1.0); 

    public PannableCanvas() { 
     setPrefSize(600, 600); 
     setStyle("-fx-background-color: lightgrey; -fx-border-color: blue;"); 

     // add scale transform 
     scaleXProperty().bind(myScale); 
     scaleYProperty().bind(myScale); 
    } 

    /** 
    * Add a grid to the canvas, send it to back 
    */ 
    public void addGrid() { 

     double w = getBoundsInLocal().getWidth(); 
     double h = getBoundsInLocal().getHeight(); 

     // add grid 
     Canvas grid = new Canvas(w, h); 

     // don't catch mouse events 
     grid.setMouseTransparent(true); 

     GraphicsContext gc = grid.getGraphicsContext2D(); 

     gc.setStroke(Color.GRAY); 
     gc.setLineWidth(1); 

     // draw grid lines 
     double offset = 50; 
     for(double i=offset; i < w; i+=offset) { 
      gc.strokeLine(i, 0, i, h); 
      gc.strokeLine(0, i, w, i); 
     } 

     getChildren().add(grid); 

     grid.toBack(); 
    } 

    public double getScale() { 
     return myScale.get(); 
    } 

    public void setScale(double scale) { 
     myScale.set(scale); 
    } 

    public void setPivot(double x, double y) { 
     setTranslateX(getTranslateX()-x); 
     setTranslateY(getTranslateY()-y); 
    } 
} 


/** 
* Mouse drag context used for scene and nodes. 
*/ 
class DragContext { 

    double mouseAnchorX; 
    double mouseAnchorY; 

    double translateAnchorX; 
    double translateAnchorY; 

} 

/** 
* Listeners for making the nodes draggable via left mouse button. Considers if parent is zoomed. 
*/ 
class NodeGestures { 

    private DragContext nodeDragContext = new DragContext(); 

    PannableCanvas canvas; 

    public NodeGestures(PannableCanvas canvas) { 
     this.canvas = canvas; 

    } 

    public EventHandler<MouseEvent> getOnMousePressedEventHandler() { 
     return onMousePressedEventHandler; 
    } 

    public EventHandler<MouseEvent> getOnMouseDraggedEventHandler() { 
     return onMouseDraggedEventHandler; 
    } 

    private EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() { 

     public void handle(MouseEvent event) { 

      // left mouse button => dragging 
      if(!event.isPrimaryButtonDown()) 
       return; 

      nodeDragContext.mouseAnchorX = event.getSceneX(); 
      nodeDragContext.mouseAnchorY = event.getSceneY(); 

      Node node = (Node) event.getSource(); 

      nodeDragContext.translateAnchorX = node.getTranslateX(); 
      nodeDragContext.translateAnchorY = node.getTranslateY(); 

     } 

    }; 

    private EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() { 
     public void handle(MouseEvent event) { 

      // left mouse button => dragging 
      if(!event.isPrimaryButtonDown()) 
       return; 

      double scale = canvas.getScale(); 

      Node node = (Node) event.getSource(); 

      node.setTranslateX(nodeDragContext.translateAnchorX + ((event.getSceneX() - nodeDragContext.mouseAnchorX)/scale)); 
      node.setTranslateY(nodeDragContext.translateAnchorY + ((event.getSceneY() - nodeDragContext.mouseAnchorY)/scale)); 

      event.consume(); 

     } 
    }; 
} 

/** 
* Listeners for making the scene's canvas draggable and zoomable 
*/ 
class SceneGestures { 

    private static final double MAX_SCALE = 10.0d; 
    private static final double MIN_SCALE = .1d; 

    private DragContext sceneDragContext = new DragContext(); 

    PannableCanvas canvas; 

    public SceneGestures(PannableCanvas canvas) { 
     this.canvas = canvas; 
    } 

    public EventHandler<MouseEvent> getOnMousePressedEventHandler() { 
     return onMousePressedEventHandler; 
    } 

    public EventHandler<MouseEvent> getOnMouseDraggedEventHandler() { 
     return onMouseDraggedEventHandler; 
    } 

    public EventHandler<ScrollEvent> getOnScrollEventHandler() { 
     return onScrollEventHandler; 
    } 

    private EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() { 

     public void handle(MouseEvent event) { 

      // right mouse button => panning 
      if(!event.isSecondaryButtonDown()) 
       return; 

      sceneDragContext.mouseAnchorX = event.getSceneX(); 
      sceneDragContext.mouseAnchorY = event.getSceneY(); 

      sceneDragContext.translateAnchorX = canvas.getTranslateX(); 
      sceneDragContext.translateAnchorY = canvas.getTranslateY(); 

     } 

    }; 

    private EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() { 
     public void handle(MouseEvent event) { 

      // right mouse button => panning 
      if(!event.isSecondaryButtonDown()) 
       return; 

      canvas.setTranslateX(sceneDragContext.translateAnchorX + event.getSceneX() - sceneDragContext.mouseAnchorX); 
      canvas.setTranslateY(sceneDragContext.translateAnchorY + event.getSceneY() - sceneDragContext.mouseAnchorY); 

      event.consume(); 
     } 
    }; 

    /** 
    * Mouse wheel handler: zoom to pivot point 
    */ 
    private EventHandler<ScrollEvent> onScrollEventHandler = new EventHandler<ScrollEvent>() { 

     @Override 
     public void handle(ScrollEvent event) { 

      double delta = 1.2; 

      double scale = canvas.getScale(); // currently we only use Y, same value is used for X 
      double oldScale = scale; 

      if (event.getDeltaY() < 0) 
       scale /= delta; 
      else 
       scale *= delta; 

      scale = clamp(scale, MIN_SCALE, MAX_SCALE); 

      double f = (scale/oldScale)-1; 

      double dx = (event.getSceneX() - (canvas.getBoundsInParent().getWidth()/2 + canvas.getBoundsInParent().getMinX())); 
      double dy = (event.getSceneY() - (canvas.getBoundsInParent().getHeight()/2 + canvas.getBoundsInParent().getMinY())); 

      canvas.setScale(scale); 

      // note: pivot value must be untransformed, i. e. without scaling 
      canvas.setPivot(f*dx, f*dy); 

      event.consume(); 

     } 

    }; 


    public static double clamp(double value, double min, double max) { 

     if(Double.compare(value, min) < 0) 
      return min; 

     if(Double.compare(value, max) > 0) 
      return max; 

     return value; 
    } 
} 



/** 
* An application with a zoomable and pannable canvas. 
*/ 
public class ZoomAndScrollApplication extends Application { 
    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage stage) { 

     Group group = new Group(); 

     // create canvas 
     PannableCanvas canvas = new PannableCanvas(); 

     // we don't want the canvas on the top/left in this example => just 
     // translate it a bit 
     canvas.setTranslateX(100); 
     canvas.setTranslateY(100); 

     // create sample nodes which can be dragged 
     NodeGestures nodeGestures = new NodeGestures(canvas); 

     Label label1 = new Label("Draggable node 1"); 
     label1.setTranslateX(10); 
     label1.setTranslateY(10); 
     label1.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
     label1.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

     Label label2 = new Label("Draggable node 2"); 
     label2.setTranslateX(100); 
     label2.setTranslateY(100); 
     label2.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
     label2.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

     Label label3 = new Label("Draggable node 3"); 
     label3.setTranslateX(200); 
     label3.setTranslateY(200); 
     label3.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
     label3.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

     Circle circle1 = new Circle(300, 300, 50); 
     circle1.setStroke(Color.ORANGE); 
     circle1.setFill(Color.ORANGE.deriveColor(1, 1, 1, 0.5)); 
     circle1.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
     circle1.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

     Rectangle rect1 = new Rectangle(100,100); 
     rect1.setTranslateX(450); 
     rect1.setTranslateY(450); 
     rect1.setStroke(Color.BLUE); 
     rect1.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.5)); 
     rect1.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
     rect1.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

     canvas.getChildren().addAll(label1, label2, label3, circle1, rect1); 

     group.getChildren().add(canvas); 

     // create scene which can be dragged and zoomed 
     Scene scene = new Scene(group, 1024, 768); 

     SceneGestures sceneGestures = new SceneGestures(canvas); 
     scene.addEventFilter(MouseEvent.MOUSE_PRESSED, sceneGestures.getOnMousePressedEventHandler()); 
     scene.addEventFilter(MouseEvent.MOUSE_DRAGGED, sceneGestures.getOnMouseDraggedEventHandler()); 
     scene.addEventFilter(ScrollEvent.ANY, sceneGestures.getOnScrollEventHandler()); 

     stage.setScene(scene); 
     stage.show(); 

     canvas.addGrid(); 

    } 
} 
+0

。あなたの試みを質問に 'Group'と一緒に入れて、このアプローチがどうして失敗するかを記述してください。 – fabian

+0

論理を教えてください。ユーザーが 'Circle'または' Rectangle'をドラッグしたときに、両方が削除されて他のコンテナに追加されたらどうでしょうか? – GOXR3PLUS

+0

okプロジェクトの作成をお待ちしております – stronglion3001

答えて

1

ますGroupを使用して私たちに言ったが動作しません。これは単に本当ではありませんし、コード内のわずかな変更は、使用して同時にCircleRectangleを移動するために必要ですGroup:右行われていれば、動作するはずです `Group`を使用して

Circle circle1 = new Circle(300, 300, 50); 
circle1.setStroke(Color.ORANGE); 
circle1.setFill(Color.ORANGE.deriveColor(1, 1, 1, 0.5)); 
// circle1.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
// circle1.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

Rectangle rect1 = new Rectangle(100, 100); 
rect1.setTranslateX(450); 
rect1.setTranslateY(450); 
rect1.setStroke(Color.BLUE); 
rect1.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.5)); 
// rect1.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
// rect1.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

Group g = new Group(rect1, circle1); 
g.addEventFilter(MouseEvent.MOUSE_PRESSED, nodeGestures.getOnMousePressedEventHandler()); 
g.addEventFilter(MouseEvent.MOUSE_DRAGGED, nodeGestures.getOnMouseDraggedEventHandler()); 

canvas.getChildren().addAll(label1, label2, label3, g); 
+0

私はそのdoumbだったし、キャンバスの子供たちにグループを追加しませんでした!どうも – stronglion3001

関連する問題