2012-11-29 18 views
7

Tôi đang xây dựng một ứng dụng trong JavaFx 2.2 bao gồm một ngăn phân tách với một bảng thành phần ở bên trái và một bảng làm việc ở bên phải. Về cơ bản những gì tôi muốn làm là một trình soạn thảo wysiwyg đơn giản, nơi bạn kéo thành phần từ trái sang phải, sau đó sắp xếp chúng ở phía bên phải.Thực hiện kéo và thả như trong Trình tạo cảnh

Tôi đã dành vài ngày cố gắng để thực hiện các tính năng tương tự drag-and-drop có SceneBuilder, mà không may mắn ..

Tiếp theo mẫu tại http://docs.oracle.com/javafx/2/drag_drop/HelloDragAndDrop.java.html tôi đã quản lý để có được một drag- và thả làm việc nhưng tôi không thể tìm thấy bất kỳ cách nào để thay đổi biểu tượng tệp mặc định xuất hiện khi bạn đang kéo (và thay thế bằng ảnh chụp của thành phần tôi đang kéo) và cách hiển thị biểu tượng bị cấm khi bạn kết thúc một thứ gì đó bạn không thể bỏ cuộc.

Bất kỳ sự giúp đỡ (có thể là lời khuyên, đoạn mã, mẫu hoặc khác) sẽ được đánh giá rất nhiều :)

Cảm ơn!

Trả lời

16

[UPDATE]

Cuối cùng quản lý nó bản thân mình:

/* The 'sceneRoot' object is the root Node of the scene graph 
* stage.setScene(new Scene(sceneRoot, 1280, 1024)); 
*/ 

private ImageView dragImageView = new ImageView(); 
private Node dragItem; 

_

rightPane.setOnMouseDragEntered(new EventHandler<MouseDragEvent>() { 
    public void handle(MouseDragEvent e) { 
     rightPane.setStyle("-fx-border-color:red;-fx-border-width:2;-fx-border-style:solid;"); 
     e.consume(); 
    } 
}); 
rightPane.setOnMouseDragExited(new EventHandler<MouseDragEvent>() { 
    public void handle(MouseDragEvent e) { 
     rightPane.setStyle("-fx-border-style:none;"); 
     e.consume(); 
    } 
}); 
rightPane.setOnMouseDragReleased(new EventHandler<MouseDragEvent>() { 
    public void handle(MouseDragEvent e) { 
     //TODO: add new instance of dragItem to rightPane 
     e.consume(); 
    } 
}); 

_

private void addGesture(final Node node) { 
    node.setOnDragDetected(new EventHandler<MouseEvent>() { 
     public void handle(MouseEvent e) { 

      SnapshotParameters snapParams = new SnapshotParameters(); 
      snapParams.setFill(Color.TRANSPARENT); 
      dragImageView.setImage(node.snapshot(snapParams, null)); 

      sceneRoot.getChildren().add(dragImageView); 

      dragImageView.startFullDrag(); 
      e.consume(); 
     } 
    }); 
    node.setOnMouseDragged(new EventHandler<MouseEvent>() { 
     public void handle(MouseEvent e) { 
      Point2D localPoint = sceneRoot.sceneToLocal(new Point2D(e.getSceneX(), e.getSceneY())); 
      dragImageView.relocate(
        (int)(localPoint.getX() - dragImageView.getBoundsInLocal().getWidth()/2), 
        (int)(localPoint.getY() - dragImageView.getBoundsInLocal().getHeight()/2) 
      ); 
      e.consume(); 
     } 
    }); 
    node.setOnMouseEntered(new EventHandler<MouseEvent>() { 
     public void handle(MouseEvent e) { 
      node.setCursor(Cursor.HAND); 
     } 
    }); 
    node.setOnMousePressed(new EventHandler<MouseEvent>() { 
     public void handle(MouseEvent e) { 
      dragItem = node; 
      dragImageView.setMouseTransparent(true); 
      node.setMouseTransparent(true); 
      node.setCursor(Cursor.CLOSED_HAND); 
     } 
    }); 
    node.setOnMouseReleased(new EventHandler<MouseEvent>() { 
     public void handle(MouseEvent e) { 
      dragItem = null; 
      dragImageView.setMouseTransparent(false); 
      node.setMouseTransparent(false); 
      node.setCursor(Cursor.DEFAULT); 
      sceneRoot.getChildren().remove(dragImageView); 
     } 
    }); 

} 
+1

Làm việc tốt. [Tính năng xem chế độ xem] (http://javafx-jira.kenai.com/browse/RT-14730?focusedCommentId=317064#) được lên lịch để được thêm vào nền tảng JavaFX trong bản phát hành trong tương lai, có khả năng là jdk8. – jewelsea

+0

Tôi cố gắng triển khai lại giải pháp cho một ListView, nhưng không biết, loại biến cảnh trong trình xử lý setOnDragDetected là gì. Nó không có Scene, vì Scene không có phương thức getChildern(). – andreas

+0

Đối tượng 'cảnh' thực sự là nút gốc của biểu đồ cảnh. Tôi đã cập nhật mã của mình với các nhận xét và được đổi tên thành scene bởi sceneRoot để hiểu rõ hơn. Cảm ơn vì đã nêu bật điều đó;) – Badisi

2

lẽ muộn, nhưng với tùy chọn setDragView, giờ đây càng được mô phỏng nhiều hơn)

// Cursor Display for Drag&Drop 
source.setOnMouseEntered(e -> source.setCursor(Cursor.OPEN_HAND)); 
source.setOnMousePressed(e -> source.setCursor(Cursor.CLOSED_HAND)); 
source.setOnMouseReleased(e -> source.setCursor(Cursor.DEFAULT)); 

// Manage drag 
source.setOnDragDetected(event -> { 
    /* drag was detected, start a drag-and-drop gesture*/ 
    Dragboard db = source.startDragAndDrop(TransferMode.MOVE); 

    // Visual during drag 
    SnapshotParameters snapshotParameters = new SnapshotParameters(); 
    snapshotParameters.setFill(Color.TRANSPARENT); 
    db.setDragView(source.snapshot(snapshotParameters, null)); 

    /* Put a string on a dragboard */ 
    ClipboardContent content = new ClipboardContent(); 
    content.putString(source.getText()); 
    db.setContent(content); 

    event.consume(); 
});