简体   繁体   中英

Make different things occur on Mouse Pressed depending on Object in Javafx

I want the mouse clicked event to either drag the existing circle or create a new circle if the mouse clicked event occurs outside of an existing circle. Right now the code will drag the circle, but also creates a new one on top of the other circle. I would really appreciate any help on cleaning the code up and making it do one or the other. Here is the code. Ive been trying to do all kinds of different things to get it to work, but I can't figure out how to get it to only do one or the other.

import javafx.application.Application;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.control.ChoiceBox;
import javafx.collections.FXCollections;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;

public class Main extends Application {

    double orgSceneX, orgSceneY;
    double orgTranslateX, orgTranslateY;

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Drawing Operations Test");
        Group root = new Group();
        Pane canvas = new Pane();
        canvas.setStyle("-fx-background-color: black;");
        canvas.setPrefSize(200,200);
        Rectangle rectangle = new Rectangle(100,100,Color.RED);
        rectangle.relocate(70,70);
        canvas.getChildren().add(rectangle);

        canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, 
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent e) {
                        Object source = e.getSource();
                        if (!(source instanceof Circle)) {
                            Circle circle = new Circle(20,Color.BLUE);
                            circle.setCursor(Cursor.MOVE);
                            circle.setOnMousePressed(circleOnMousePressedEventHandler);
                        circle.setOnMouseDragged(circleOnMouseDraggedEventHandler);
                        circle.relocate((e.getX()-10),(e.getY()-10));
                        canvas.getChildren().add(circle);
                        System.out.println(source);
                    }


                }

    });

    root.getChildren().add(canvas);
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
}



EventHandler<MouseEvent> circleOnMousePressedEventHandler = 
        new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent t) {
            orgSceneX = t.getSceneX();
            orgSceneY = t.getSceneY();
            orgTranslateX = ((Circle)(t.getSource())).getTranslateX();
            orgTranslateY = ((Circle)(t.getSource())).getTranslateY();
            System.out.println(t.getSource());

        }
    };

    EventHandler<MouseEvent> circleOnMouseDraggedEventHandler = 
        new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent t) {
            double offsetX = t.getSceneX() - orgSceneX;
            double offsetY = t.getSceneY() - orgSceneY;
            double newTranslateX = orgTranslateX + offsetX;
            double newTranslateY = orgTranslateY + offsetY;

            ((Circle)(t.getSource())).setTranslateX(newTranslateX);
            ((Circle)(t.getSource())).setTranslateY(newTranslateY);
        }
    };
}

I found it! the answer for me was creating an if else statement and consuming the event on the circle. I'm sure there is a much more elegant way to do this, but I'm not too elegant in Java..... yet.

public class Main extends Application {

double orgSceneX, orgSceneY;
double orgTranslateX, orgTranslateY;
Pane canvas;

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

@Override
public void start(Stage primaryStage) {
    primaryStage.setTitle("Drawing Operations Test");
    Group root = new Group();
    canvas = new Pane();
    canvas.setStyle("-fx-background-color: black;");
    canvas.setPrefSize(200,200);
    Rectangle rectangle = new Rectangle(100,100,Color.RED);
    rectangle.relocate(70,70);
    canvas.getChildren().add(rectangle);
    canvas.setOnMousePressed(MousePressedEventHandler);





    root.getChildren().add(canvas);
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
}



EventHandler<MouseEvent> MousePressedEventHandler = 
        new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent e) {
            if (e.getSource() instanceof Circle) {
                orgSceneX = e.getSceneX();
                orgSceneY = e.getSceneY();
                orgTranslateX = ((Circle)(e.getSource())).getTranslateX();
                orgTranslateY = ((Circle)(e.getSource())).getTranslateY();
                e.consume();
                System.out.println(e.getSource());

            }
            else {

                Circle circle = new Circle(20,Color.BLUE);
                circle.setCursor(Cursor.MOVE);
                circle.setOnMousePressed(MousePressedEventHandler);
                circle.setOnMouseDragged(MouseDraggedEventHandler);
                circle.relocate((e.getX()-10),(e.getY()-10));
                canvas.getChildren().add(circle);
                System.out.println(e.getSource());
            }
        }
    };

    EventHandler<MouseEvent> MouseDraggedEventHandler = 
        new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent t) {
            double offsetX = t.getSceneX() - orgSceneX;
            double offsetY = t.getSceneY() - orgSceneY;
            double newTranslateX = orgTranslateX + offsetX;
            double newTranslateY = orgTranslateY + offsetY;

            ((Circle)(t.getSource())).setTranslateX(newTranslateX);
            ((Circle)(t.getSource())).setTranslateY(newTranslateY);
        }
    };

}

You can consume the event on the child node (circle) before it delegates to the Parent (pane).

EventHandler<MouseEvent> circleOnMousePressedEventHandler = event -> {
    orgSceneX = event.getSceneX();
    orgSceneY = event.getSceneY();
    orgTranslateX = ((Circle) (event.getSource())).getTranslateX();
    orgTranslateY = ((Circle) (event.getSource())).getTranslateY();
    event.consume();
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM