如何在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;
}
}
答案 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;
}
}