2016-09-04 7 views
0

У меня есть GridPane of Circles, и я хочу, чтобы иметь возможность перетаскивать один круг поверх другого и иметь цвет от первого, который будет применен ко второму.JavaFX Перетащите фигуру на другую фигуру

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу получить целевой круг для обнаружения dragEntered или dragOver. Я смог реализовать это успешно с помощью Labels, но по какой-то причине Circle не дает такого же эффекта.

Я видел некоторые квазирешения, которые включали установку circle.setMouseTransparent (true), так что узел под перетаскиваемый узел может видеть перетаскивание, но и здесь не повезло.

Вот ссылка на код, который делает подобную вещь с помощью меток: Hello Drag and Drop

Вот применимое фрагмент моего кода:

   circle.setOnDragDetected(new EventHandler<MouseEvent>() { 
       @Override 
       public void handle(MouseEvent event) { 

        Dragboard db = circle.startDragAndDrop(TransferMode.ANY); 

        System.out.print("Dragging..."); 
        System.out.println("From row: " + draggedFromRow + " From col: " + draggedFromCol); 

        circle.setLayoutX(event.getSceneX()); 
        circle.setLayoutY(event.getSceneY()); 


        event.consume(); 
       } 
      }); 

      circle.setOnDragOver(new EventHandler <DragEvent>() { 

       public void handle(DragEvent event) { 
        System.out.println("onDragOver"); 

        event.acceptTransferModes(TransferMode.ANY); 

        event.consume(); 
       } 
      }); 


      circle.setOnDragDropped(new EventHandler<DragEvent>() { 
       @Override 
       public void handle(DragEvent event) { 

        int toCol = Integer.valueOf(circle.getId().substring(0, 1)); 
        int toRow = Integer.valueOf(circle.getId().substring(1)); 

        performSwap(draggedFromRow, draggedFromCol, toRow, toCol); 

        System.out.print("Dragg dropped on "); 
        System.out.println(toRow + " " + toCol); 

        event.consume(); 
       } 
      }); 

      circle.setOnDragEntered(new EventHandler<DragEvent>() { 
       public void handle(DragEvent event) { 
        System.out.println("drag entered!"); 

        event.consume(); 
       } 
      }); 


      circle.setOnDragExited(new EventHandler<DragEvent>() { 
       public void handle(DragEvent event) { 
        System.out.println("drag left!"); 

        event.consume(); 
       } 
      }); 
+0

Пожалуйста ВЫВЕШУ [MCVE] или SSCCE, который воспроизводит эту проблему. Это увеличит ваши шансы получить полезный ответ (а также поможет вам найти проблему). – c0der

+0

Перетаскивание IIRC фактически не будет инициировано, если вы не поместите некоторые данные в планшет. –

+0

James_D, это исправило мою проблему. Кто бы мог подумать, что вам нужно, чтобы там было просто зарегистрировать перетаскивание. Возможно, я просто пропустил это в документации. Благодаря! –

ответ

1

James_D был правильный ответ на этот вопрос в своем комментарии выше , Кажется, что даже для того, чтобы регистр круга регистрировал перетаскивание, вам нужно передать некоторые данные в Dragboard (даже если вы не хотите передавать данные на узел).

Это был добавлен в мой circle.setOnDragDetected метод:

Dragboard db = circle.startDragAndDrop(TransferMode.ANY); 
ClipboardContent content = new ClipboardContent(); 
content.putString(circle.getId()); 
db.setContent(content); 

Так что метод теперь выглядит следующим образом:

  circle.setOnDragDetected(new EventHandler<MouseEvent>() { 
       @Override 
       public void handle(MouseEvent event) { 

        Dragboard db = circle.startDragAndDrop(TransferMode.ANY); 
        ClipboardContent content = new ClipboardContent(); 
        content.putString(circle.getId()); 
        db.setContent(content); 

        System.out.print("onDragDetected"); 

        event.consume(); 
       } 
      });