Как получить Node при перетаскивании мышью по позиции события в JavaFX 8? - PullRequest
0 голосов
/ 03 декабря 2018

Я создал пример кода:

package stackoverflow;

import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class GetNodeByMousePositionWhileDragged extends Application {

    private Line line;
    private Group group = new Group();

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

        AnchorPane anchorPane = new AnchorPane();

        Circle source = new Circle(30, Color.LIGHTGREEN);
        source.setStroke(Color.BLACK);
        source.setCenterX(100);
        source.setCenterY(100);

        source.setOnMousePressed(me -> {

            me.consume();

            drawLine(source, me);
        });

        source.setOnMouseDragged(me -> translateLineEnd(getPoint(me)));

        source.setOnMouseReleased(event -> group.getChildren().remove(line));

        Circle target = new Circle(30, Color.LIGHTBLUE);
        target.setStroke(Color.BLACK);
        target.setCenterX(400);
        target.setCenterY(100);

        target.setOnMousePressed(me -> {

            me.consume();

            drawLine(target, me);
        });

        target.setOnMouseDragged(me -> translateLineEnd(getPoint(me)));

        target.setOnMouseReleased(event -> group.getChildren().remove(line));

        group.getChildren().addAll(source, target);

        anchorPane.getChildren().addAll(group);

        stage.setScene(new Scene(anchorPane, 600, 400));
        stage.setMaximized(true);
        stage.show();

    }

    private void drawLine(Circle source, MouseEvent me) {

        line = new Line();
        line.setStroke(Color.BLACK);
        line.setStrokeWidth(1);

        line.startXProperty().bind(source.centerXProperty());
        line.startYProperty().bind(source.centerYProperty());

        translateLineEnd(getPoint(me));

        group.getChildren().add(line);
    }

    private void translateLineEnd(Point2D point) {

        line.setEndX(point.getX());
        line.setEndY(point.getY());
    }

    private Point2D getPoint(MouseEvent me) {

        return new Point2D(me.getSceneX(), me.getSceneY());
    }
}

Здесь я просто добавляю два круга и хочу соединить их линией, просто перетаскивая из одного круга в другой.Но проблема в том, что я хочу проверить, вошла ли мышь в целевой круг во время перетаскивания мыши из исходного круга.Когда он введен, я хочу просто привязать конечные точки линии к центральным точкам целевого круга или удалить линию при отпускании мыши, если не было введено ни одного круга, кроме исходного.

К сожалению, при перетаскивании одного круга другой кругне ловить мышиные события.Но можно получить положение мыши на сцене.Я пытался решить эту проблему, просто сохраняя все круги (у меня их куча, 10K +), повторяя каждый раз и проверяя circle.contains(me.getSceneX(), me.getSceneY()).Мне кажется, это немного дорогой способ или как изобретать колесо.

Возникает вопрос, возможно ли в JavaFX 8 правильно получить узел в соответствии с положением сцены, используя встроенные функции JavaFX?

1 Ответ

0 голосов
/ 03 декабря 2018

Вам необходимо немного изменить код:

  • Используйте MouseDragEvent s, вызвав startFullDrag для исходного узла в событии onDragDetected.
  • Set *От 1009 * до true для строки, позволяющей JavaFX доставлять MouseEvent s в круг target вместо Line.
  • Измените обработчики событий для получения других результатов, если мышьбыл выпущен на целевой круг.
private void drawLine(Circle source, MouseEvent me) {

    line = new Line();
    line.setMouseTransparent(true);
    ...
private Group group = new Group();

private boolean removeLine = true;
source.setOnMousePressed(me -> {
    me.consume();

    drawLine(source, me);
    me.setDragDetect(true); // trigger dragDetected event immediately
});
source.setOnDragDetected(evt -> {
    source.startFullDrag();
    removeLine = true;
});

...

source.setOnMouseReleased(event -> {
    if (removeLine) {
        group.getChildren().remove(line);
    }
});
target.setOnMouseDragReleased(me -> removeLine = false);
...