Обнаружение MouseDragged для нескольких узлов при удержании кнопки JavaFX - PullRequest
0 голосов
/ 01 февраля 2020

Я буду go прямо с вопросом. Как я могу реализовать систему для моего приложения, которая позволяет мне окрашивать эти прямоугольники, показанные ниже, удерживая левую кнопку мыши? И когда выпущено, это останавливает окраску. Я искал через inte rnet, но до сих пор не могу понять, как работают эти MouseEvents.

Хорошего дня!

Rectangles to color

1 Ответ

1 голос
/ 01 февраля 2020

Из документации javafx.scene.input.MouseEvent:

Жесты перетаскивания

Существует три типа перетаскивания жестов. Все они инициируются событием нажатия мыши и завершаются в результате события отпускания мыши, исходный узел решает, какой жест произойдет.

Простой жест нажатие-перетаскивание по умолчанию используется по умолчанию. Лучше всего использовать его для изменения размера фигуры, ее перетаскивания и так далее. Весь жест «нажатие-перетаскивание» доставляется одному узлу. При нажатии кнопки мыши выбирается самый верхний узел, и все последующие события мыши доставляются в тот же узел, пока кнопка не будет отпущена. Если из этих событий генерируется событие щелчка мыши, оно все равно доставляется на тот же узел.

Во время простого жеста нажатие-перетаскивание другие узлы не участвуют и не получают никаких событий. Если эти узлы должны быть вовлечены в жест, должен быть активирован полный нажатие-перетаскивание-отпускание. Этот жест лучше всего использовать для соединения узлов с помощью «проводов», перетаскивания узлов на другие узлы и т. Д. c. Этот тип жеста более подробно описан в MouseDragEvent, который содержит события, доставленные к целям жеста.

Третий тип жеста - это жест перетаскивания, поддерживаемый платформой. Он лучше всего подходит для передачи данных и работает также между (не обязательно FX) приложениями. Этот тип жеста более подробно описан в DragEvent.

В кратком изложении простой жест нажатия и отпускания активируется автоматически при нажатии кнопки мыши и доставляет все MouseEvent с источнику жеста. , Когда вы начинаете перетаскивать, в конце концов наступает событие DRAG_DETECTED. В его обработчике вы можете либо запустить полный жест нажатие-перетаскивание, вызвав метод startFullDrag на узле или сцене - начало MouseDragEvent будет доставлено к целям жеста, либо вы можете запустить жест перетаскивания, вызвав * Метод 1025 * на узле или сцене - система переключается в режим перетаскивания и начинает доставляться DragEvent s вместо MouseEvent s. Если вы не вызовете ни один из этих методов, простой жест нажатия и восстановления продолжится.

[...]

Если я правильно понимаю ваш вопрос, вы хотите чтобы можно было перетаскивать мышь над несколькими узлами и заставлять их реагировать одним движением. Вы захотите использовать жест full press-drag-release , чтобы выполнить sh это. Как задокументировано, вы должны прослушать событие DRAG_DETECTED и позвонить Node#startFullDrag() или Scene#startFullDrag(), чтобы активировать полное нажатие -релиз жест. Затем каждый «квадрат» в вашем интерфейсе должен прослушивать события MOUSE_DRAG_ENTERED. Обратите внимание, что тип события - MOUSE_DRAG_ENTERED и , а не MOUSE_ENTERED.

. Вот пример:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class App extends Application {

  @Override
  public void start(Stage primaryStage) {
    GridPane root = new GridPane();
    root.setPadding(new Insets(2));
    root.setVgap(2);
    root.setHgap(2);

    // start full press-drag-release gesture
    root.setOnDragDetected(
        event -> {
          if (event.getButton() == MouseButton.PRIMARY) {
            event.consume();
            root.startFullDrag();
          }
        });

    for (int i = 0; i < 12; i++) {
      for (int j = 0; j < 12; j++) {
        Rectangle rect = new Rectangle(50, 50, Color.WHITE);
        rect.setStroke(Color.BLACK);
        root.add(rect, i, j);

        // detect MOUSE_DRAG_ENTERED events
        rect.setOnMouseDragEntered(
            event -> {
              event.consume();
              rect.setFill(Color.BLACK);
            });
      }
    }

    primaryStage.setTitle("MouseDragEvent Example");
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
  }
}

Приведенное выше прослушивает события DRAG_DETECTED, устанавливая Node#onDragDetected свойство на root GridPane. Обратите внимание, что если вы начнете перетаскивать одну из Rectangle s, то событие будет пузыриться до root и обрабатываться вышеупомянутым обработчиком. Кроме того, поскольку вы явно упоминаете левую кнопку мыши, я добавил проверку, является ли кнопка мыши основной или нет.

Затем каждый Rectangle прослушивает MOUSE_DRAG_ENTERED события, имея их Node#onMouseDragEntered набор свойств. Эти события будут доставлены только при действующем жесте полное нажатие-перетаскивание .

...