2014-11-22 4 views
0

Я работаю над приложением, которое нужно перемещать узлами на панели.Правильный способ перемещения узла JavaFx8 вокруг

Я только недавно начал изучать javaFx 8, поэтому у меня есть общее представление о рабочем процессе, но пока мне удалось получить рабочий код перетаскиваемого узла, он использует node.setTranslateX() и .setTranslateY().

Все это нормально, пока я не попытался сделать привязку узла к сетке, которая делит площадь сцены на 10 делений высоты и ширины.

Всякий раз, когда я пытаюсь использовать modulos, чтобы получить какие-то привязки, я застрял в том, что я называю преобразование перевода. Я хотел бы непосредственно установить координаты узла самостоятельно. Я пробовал node.relocate (x, y) безрезультатно. Что касается node.setX() или node.setY(). Кажется, они ничего не делают.

Так в основном, у меня есть два вопроса:

  • Есть ли способ, чтобы непосредственно установить координаты узла? Если да, то как?
  • Каков правильный способ привязки узла к сетке при перетаскивании его мышью?

Мой текущий код использует эти методы, чтобы перетащить узел вокруг:

public class Boat extends ImageView { 
    private int size ; 
    private String name ; 
    private Double dragDeltaX, dragDeltaY; 

    //Constructor etc here// 

    this.setOnMousePressed(event -> { 
     this.setCursor(Cursor.CLOSED_HAND); 
     dragDeltaX = this.getLayoutX() + event.getX(); 
     dragDeltaY = this.getLayoutY() + event.getY(); 
    }); 

    this.setOnMouseReleased(event -> { 
     this.setCursor(Cursor.OPEN_HAND); 
     this.relocate(event.getSceneX(), event.getSceneY()); 
    }); 

    this.setOnMouseDragged(event -> { 
     this.setTranslateX(event.getSceneX() - dragDeltaX); 
     this.setTranslateY(event.getSceneY() - dragDeltaY); 
    }); 

    this.setOnMouseEntered(event -> { 
     this.setCursor(Cursor.OPEN_HAND); 
    }); 
} 

Заранее спасибо за помощь,

+0

Какой контейнер ('Pane') вы вкладываете в это? –

+0

@James_D Stackpane – Skwiggs

ответ

3

В большинстве Pane подклассов, если Node является managed, то родительский панель узла будет управлять своими layoutX и layoutY свойствами. Поэтому установка layoutX и layoutY для этих узлов не будет иметь видимого влияния на положение узла.

Преобразования (включая перевод, определяемый translateX и translateY) применяются к узлам после вычислений компоновки (независимо от того, управляется ли узел его родителем или нет).

Таким образом, один из способов управления перетаскиванием - это просто управлять свойствами translateX и translateY. Другим способом является управление объектами layoutX и layoutY (путем установки их напрямую или путем вызова relocate) и убедитесь, что узел не управляется его родителем. Я бы не рекомендовал смешивать два метода, так как вашему коду будет труднее следовать.

Вы можете сделать узел неуправляемый setManaged(false) на узле, или помещая его в Pane вместо одного из подклассов (Pane не удается расположение его дочерних узлов).

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.image.WritableImage; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class ImageViewDragExample extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     Image image = createImage(); 
     DraggableImageView imageView = new DraggableImageView(image); 

     // if the node is placed in a parent that manages its child nodes, 
     // you must call setManaged(false); 

//  imageView.setManaged(false); 
//  StackPane root = new StackPane(imageView); 

     // or use a plain `Pane`, which does not manage its child nodes: 
     Pane root = new Pane(imageView); 

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

    private Image createImage() { 
     WritableImage image = new WritableImage(50, 50); 
     for (int y = 0 ; y < 50; y++) { 
      for (int x = 0 ; x < 50 ; x++) { 
       Color c ; 
       if ((x > 20 && x < 30) || (y > 20 && y < 30)) { 
        c = Color.AZURE ; 
       } else { 
        c = Color.CORNFLOWERBLUE ; 
       } 
       image.getPixelWriter().setColor(x, y, c); 
      } 
     } 
     return image ; 
    } 

    public static class DraggableImageView extends ImageView { 
     private double mouseX ; 
     private double mouseY ; 
     public DraggableImageView(Image image) { 
      super(image); 

      setOnMousePressed(event -> { 
       mouseX = event.getSceneX() ; 
       mouseY = event.getSceneY() ; 
      }); 

      setOnMouseDragged(event -> { 
       double deltaX = event.getSceneX() - mouseX ; 
       double deltaY = event.getSceneY() - mouseY ; 
       relocate(getLayoutX() + deltaX, getLayoutY() + deltaY); 
       mouseX = event.getSceneX() ; 
       mouseY = event.getSceneY() ; 
      }); 
     } 
    } 

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

Большое спасибо за объяснение! Я вообще не знал об управляемой собственности! – Skwiggs

+0

, и если вам интересно, почему узел, который вы перетаскиваете, отстает от положения курсора мыши, пожалуйста, проголосуйте за мою проблему: https://javafx-jira.kenai.com/browse/RT-34608 – Boomah

+0

Вопрос: Бумахские ссылки были переименован в: https://bugs.openjdk.java.net/browse/JDK-8087922 – jewelsea

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