JavaFX:如何对形状进行分组以进行拖动?

时间:2015-02-17 17:01:26

标签: javafx grouping shapes

如何在JavaFX中对形状(例如圆圈)进行分组以便将它们拖动?示例代码基于Oracle教程。每个圆圈都可以移动。我想在拖动时单独移动蓝色圆圈。我想在点击并拖动绿色和蓝色圆圈时单击并拖动红色圆圈时,移动绿色和蓝色圆圈。有什么想法吗?

public class DragGroupSample extends Application {

    public static void main( String[] args ) {
        launch();
    }

    private void makeDraggable( Circle circle ) {
        DragContext dragContext = new DragContext();

        // --- remember initial coordinates of mouse cursor and node
        circle.addEventFilter( MouseEvent.MOUSE_PRESSED, (
                final MouseEvent mouseEvent ) -> {
            dragContext.dx = mouseEvent.getX() - circle.getCenterX();
            dragContext.dy = mouseEvent.getY() - circle.getCenterY();
        } );

        // --- Shift node calculated from mouse cursor movement
        circle.addEventFilter( MouseEvent.MOUSE_DRAGGED, (
                final MouseEvent mouseEvent ) -> {
            circle.setCenterX( mouseEvent.getX() + dragContext.dx );
            circle.setCenterY( mouseEvent.getY() + dragContext.dy );
        } );

        // --- Drop card onto allowed target field
        circle.addEventFilter( MouseEvent.MOUSE_RELEASED, (
                final MouseEvent mouseEvent ) -> {
            circle.setCenterX( mouseEvent.getX() + dragContext.dx );
            circle.setCenterY( mouseEvent.getY() + dragContext.dy );
        } );
    }

    @Override
    public void start( Stage primaryStage ) throws Exception {
        Circle[] circles = new Circle[3];
        circles[0] = new Circle( 30.0, 30.0, 30.0, Color.RED );
        circles[1] = new Circle( 45.0, 45.0, 30.0, Color.GREEN );
        circles[2] = new Circle( 60.0, 60.0, 30.0, Color.BLUE );
        for ( Circle circle : circles ) {
            makeDraggable( circle );
        }

        Group root = new Group();
        root.getChildren().addAll( circles[0], circles[1], circles[2] );
        primaryStage.setResizable( false );
        primaryStage.setScene( new Scene( root, 400, 350 ) );
        primaryStage.setTitle( DragGroupSample.class.getSimpleName() );
        primaryStage.show();
    }

    private static final class DragContext {
        public double dx, dy;
    }
}

1 个答案:

答案 0 :(得分:1)

只需移动您想要移动的所有圆圈即可。相对于固定的东西(如场景),可能更容易存储最后一个鼠标位置,而不是相对于圆形工作。

这是单向的,有很多:

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class DragGroupSample extends Application {

    public static void main( String[] args ) {
        launch();
    }

    // list of nodes that are dragged. Can be modified at any time (on the FX Application Thread):
    private final List<Circle> nodesToDrag = new ArrayList<>();

    private final Circle[] circles = new Circle[3] ;

    private void makeDraggable( Circle circle ) {
        MouseLocation lastMouseLocation = new MouseLocation();

        // --- remember initial coordinates of mouse cursor and node
        circle.addEventFilter( MouseEvent.MOUSE_PRESSED, (
                final MouseEvent mouseEvent ) -> {
            lastMouseLocation.x = mouseEvent.getSceneX() ;
            lastMouseLocation.y = mouseEvent.getSceneY() ;

            // just some example logic to modify the list of dragged nodes:
            boolean found = false ;
            for (Circle c : circles) {
                if (c == circle) found = true ;
                if (found) nodesToDrag.add(c);
            }
        } );

        // --- Shift node calculated from mouse cursor movement
        circle.addEventFilter( MouseEvent.MOUSE_DRAGGED, (
                final MouseEvent mouseEvent ) -> {
                    double deltaX = mouseEvent.getSceneX() - lastMouseLocation.x ;
                    double deltaY = mouseEvent.getSceneY() - lastMouseLocation.y ;
                    for (Circle c : nodesToDrag) {
                        c.setCenterX( c.getCenterX() + deltaX  );
                        c.setCenterY( c.getCenterY() + deltaY );
                    }
                    lastMouseLocation.x = mouseEvent.getSceneX();
                    lastMouseLocation.y = mouseEvent.getSceneY();
        } );

        circle.addEventFilter(MouseEvent.MOUSE_RELEASED, mouseEvent -> nodesToDrag.clear());

    }

    @Override
    public void start( Stage primaryStage ) throws Exception {

        circles[0] = new Circle( 30.0, 30.0, 30.0, Color.RED );
        circles[1] = new Circle( 45.0, 45.0, 30.0, Color.GREEN );
        circles[2] = new Circle( 60.0, 60.0, 30.0, Color.BLUE );

        for ( Circle circle : circles ) {
            makeDraggable( circle );
        }

        Group root = new Group();
        root.getChildren().addAll( circles[0], circles[1], circles[2] );
        primaryStage.setResizable( false );
        primaryStage.setScene( new Scene( root, 400, 350 ) );
        primaryStage.setTitle( DragGroupSample.class.getSimpleName() );
        primaryStage.show();
    }

    private static final class MouseLocation {
        public double x, y;
    }
}