2014-11-22 88 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