2014-11-22 90 views
0

我正在研究需要在窗格上移动节点的应用程序。移动JavaFx8节点的正确方法

我刚刚开始学习javaFx 8,所以我对工作流有了一些了解,但是当我设法使可工作的可拖动节点代码工作时,它使用了node.setTranslateX()和.setTranslateY()。

这一切都很好,直到我试图使节点捕捉到一个网格,该网格将高度和宽度细分中的场景区域分开。

每当我尝试使用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')你把它放进去? – 2014-11-22 17:11:50

+0

@James_D Stackpane – Skwiggs 2014-11-22 21:01:51

回答

3

在大多数Pane子类,如果Nodemanaged,则父该节点的窗格将管理其layoutXlayoutY属性。因此,为这些节点设置layoutXlayoutY将对节点的位置没有明显影响。

在布局计算后(无论节点是否由其父节点管理),转换(包括由translateXtranslateY定义的转换)应用于节点。

所以管理拖动的一种方法就是操纵translateXtranslateY属性。另一种方法是操纵layoutXlayoutY属性(通过直接设置它们或通过调用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 2014-11-24 12:15:25

+0

,如果您想知道为什么您拖动的节点落后于鼠标光标的位置,请为我的问题投票:https://javafx-jira.kenai.com/browse/RT-34608 – Boomah 2014-11-24 14:40:34

+0

该问题Boomah引用已改名为:https://bugs.openjdk.java.net/browse/JDK-8087922 – jewelsea 2017-02-13 19:08:18