2013-12-19 3 views
4

У меня есть область под названием «R» и узел «N». N является единственным ребенком на R. Рассмотрим поведение:Как перенаправить MouseEvent.MOUSE_PRESSED на другой узел?

  1. пользователь нажимает левую кнопку мыши на какой-то части R
  2. N (который находится где-то на R) движется так, что она сосредоточена на в месте, где пользователь нажал
  3. пользователь отпускает левую кнопку мыши, а затем снова нажимает его, не перемещая мышь
  4. с нажатой левой кнопкой мыши, пользователь перетаскивает мышь, а N теперь следует за мышью курсор вокруг, поскольку он перетаскивается.

У меня нет проблем с реализацией поведения, которое я только что описал. Я поставил обработчик MOUSE_PRESSED на R, который реализует шаг 2. И я поместил обработчик MOUSE_DRAGGED на N, который реализует шаг 4. JavaFX автоматически направляет MouseEvents этим обработчикам на R и N для прессов на шагах 1 и 3 соответственно.

Проблема:

мне нужно сделать это без шага 3. То есть, пользователь не должен нажимать спусковую-пресс-перетаскивание, а нужно просто нажать-перетащить, и N должны «прыгать» в местоположение мыши на «нажмите», а затем немедленно начать получать события MOUSE_DRAGGED.

К сожалению, этого не происходит. Этот щелчок, который я пытаюсь пропустить, кажется необходимым, в противном случае события перетаскивания происходят на R вместо N.

Я думаю, что решение будет включать повторную рассылку начальной MOUSE_PRESSED или что-то в этом направлении , (? Или лучший способ решить мою проблему) Кто-нибудь знает способ сделать это

+0

Следует также отметить, что на практике я на самом деле нужно сделать это для большого числа различных узлов (т.е. У меня много N), поэтому я не могу полагаться на область R, чтобы переместить N (см. Решение James_D ниже.) По причинам инкапсуляции мне нужно, чтобы N контролировал перемещение. – Xanatos

+0

Какова логика, которую вы используете, чтобы определить, какая N должна привязываться к позиции начального щелчка мыши? – OttPrime

+0

Я пишу пользовательский API для отображения произвольных узлов, созданных пользователями API. «Текущий активный» узел (как определено пользователем) - это тот, который привязывается к позиции мыши. Кроме того, узел должен получать события перетаскивания, так как фактическое поведение, которое происходит во время этих перетаскиваний, также может быть настроено (поведение, которое я описал в моем простом примере, является лишь одной из многих возможных реакций, которые могут быть использованы определенными узлами.) – Xanatos

ответ

2

узел имеет API, чтобы отметить его как цель перетаскивания жестов:

общественной ничтожной startFullDrag()

запускает полный пресс-релиз перетащить жест с этим узлом в качестве жеста источника. Этот метод можно вызвать только из обработчика события DRAG_DETECTED . Более подробную информацию о перетаскивании жестов можно найти в обзоре MouseEvent и MouseDragEvent в .

Предполагая, что круг является вашим текущим активным узлом на панели (код заимствования/имена из ответа Джеймса), коллаборационисты обработчики на

  • mousePressed на панели, которая щелкает положение окружности к току расположение
  • dragDetected на панели, которая вызывает startsFullDrag на окружности
  • dragAny на круг, который делает фактическое перемещение

В коде:

pane.setOnMousePressed(new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent event) { 
     circle.setCenterX(event.getX()); 
     circle.setCenterY(event.getY()); 
    } 
}); 
pane.setOnDragDetected(new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent event) { 
     circle.startFullDrag(); 
    } 
}); 
circle.addEventHandler(MouseDragEvent.ANY, new EventHandler<MouseDragEvent>() { 
    @Override 
    public void handle(MouseDragEvent event) { 
     circle.setCenterX(event.getX()); 
     circle.setCenterY(event.getY()); 
    } 
}); 
+0

Да, это лучшее решение для моей ситуации, хотя решение, предлагаемое James_D, будет работать и во многих случаях. Благодаря! – Xanatos

2

Я выбрал самый простой узел для работы с для этого, но я думаю, что это будет работать вообще:

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.stage.Stage; 

public class ClickAndDragTest extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     final Pane pane = new Pane(); 
     final Circle circle = new Circle(100, 100, 50, Color.CORNFLOWERBLUE); 
     pane.getChildren().add(circle); 

     pane.setOnMousePressed(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent event) { 
       circle.setCenterX(event.getX()); 
       circle.setCenterY(event.getY()); 
      } 
     }); 
     pane.setOnMouseDragged(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent event) { 
       circle.setCenterX(event.getX()); 
       circle.setCenterY(event.getY()); 
      } 
     }); 

     final Scene scene = new Scene(pane, 400, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

Спасибо за предложение; это хорошее решение проблемы, которую я описал. К сожалению, я описал очень упрощенную версию моей проблемы, и я забыл, что мне нужно, чтобы N отвечал за собственный код позиционирования. Я не могу легко полагаться на R на позицию N. – Xanatos

Смежные вопросы