Q:

Drag nodes like in a patience/Klondike card game

I'm doing a Klondike game. The logic is all working. I'm just having trouble with the UI in javafx.
I've been trying to move/drag the cards from the 'tableau pile' arround without the expected result.
My card is a ImageView with an Image inside. The cards are inside a Pane:
Pane tableau = new Pane();
for (int i = 0; i < n; i++) {
    Image img = new Image("resources/images/" + (i + 1) + ".png");
    ImageView imgView = new ImageView(img);
    imgView.setY(i * 20);
    //imgView Mouse Events here
    tableau.getChildren().add(imgView);
}

I tried:
imgView.setOnMousePressed((MouseEvent mouseEvent) -> {
    dragDelta.x = imgView.getLayoutX() - mouseEvent.getSceneX();
    dragDelta.y = imgView.getLayoutY() - mouseEvent.getSceneY();
});
imgView.setOnMouseDragged((MouseEvent mouseEvent) -> {
    imgView.setLayoutX(mouseEvent.getSceneX() + dragDelta.x);
    imgView.setLayoutY(mouseEvent.getSceneY() + dragDelta.y);
});

This solution dont work because I'm setting the positions so when release the card wont return to where it was, and because the card is colliding with other UI objects.
Another attempt:
imgView.setOnDragDetected((MouseEvent event) -> {
    ClipboardContent content = new ClipboardContent();
    content.putImage(img);
    Dragboard db = imgView.startDragAndDrop(TransferMode.ANY);
    db.setDragView(img, 35, 50);
    db.setContent(content);
    event.consume();
});

In this solution the problems are: the card comes semitransparent, like moving a file, the cursor becames no/forbidden but other than that it works well: no collisions and the card goes to his original place if I release the mouse.
Another problem is that I dont know if I can move more than 1 card with this solution? 
My final question is, How can I move a node (in this case an ImageView) or a group of nodes, from one pile to another, like in a Solitaire Card Game?

A:

For knowing the original card position you should use the setTranslateX (and Y) instead of setLayoutX in your mouse handler. So when the user releases the card, you can simply invoke a Transition and let the card fly back to the layout position. If the user releases the card on a valid place, you set the translate coordinates to 0 and change the layout position or use relocate.
If you want to make the cards semitransparent, you could e. g. change the opacity or apply CSS.
By the way, I wouldn't use Clipboardcontent, it seems inappropriate for your needs.
You can move multiple objects with your mouse handling code. You simple have to apply the translation to multiple objects simultaneously. When you drag a pile, you determine the cards on top of the selected card and apply the transition to all of them.

Here's a quick example to show you how it could look like.
Card.java, you'll use an ImageView.
public class Card extends Rectangle {

    static Random rand = new Random();

    public Card() {

        setWidth(100);
        setHeight(200);

        Color color = createRandomColor();

        setStroke(color);
        setFill( color.deriveColor(1, 1, 1, 0.4));

    }

    public static Color createRandomColor() {

        int max = 200;

        Color color = Color.rgb( (int) (rand.nextDouble() * max), (int) (rand.nextDouble() * max), (int) (rand.nextDouble() * max));

        return color;
    }
}

Game.java, the application.
public class Game extends Application {

    static List<Card> cardList = new ArrayList<>();

    @Override
    public void start(Stage primaryStage) {

        MouseGestures mg = new MouseGestures();

        Group root = new Group();

        for( int i=0; i < 10; i++) {

            Card card = new Card();
            card.relocate( i * 20, i * 10);

            mg.makeDraggable(card);

            cardList.add( card);
        }

        root.getChildren().addAll( cardList);

        Scene scene = new Scene( root, 1600, 900);

        primaryStage.setScene( scene);
        primaryStage.show();

    }

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

    // TODO: don't use a static method, I only added for the example 
    public static List<Card> getSelectedCards( Card currentCard) {

        List<Card> selectedCards = new ArrayList<>();

        int i = cardList.indexOf(currentCard);
        for( int j=i + 1; j < cardList.size(); j++) {
            selectedCards.add( cardList.get( j));
        }

        return selectedCards;
    }

}

MouseGestures.java, the mouse handling mechanism.
public class MouseGestures {

    final DragContext dragContext = new DragContext();

    public void makeDraggable(final Node node) {

        node.setOnMousePressed(onMousePressedEventHandler);
        node.setOnMouseDragged(onMouseDraggedEventHandler);
        node.setOnMouseReleased(onMouseReleasedEventHandler);

    }

    EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {

            dragContext.x = event.getSceneX();
            dragContext.y = event.getSceneY();

        }
    };

    EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {

            Node node = (Node) event.getSource();

            double offsetX = event.getSceneX() - dragContext.x;
            double offsetY = event.getSceneY() - dragContext.y;

            node.setTranslateX(offsetX);
            node.setTranslateY(offsetY);

            // same for the other cards
            List<Card> list = Game.getSelectedCards( (Card) node);
            for( Card card: list) {
                card.setTranslateX(offsetX);
                card.setTranslateY(offsetY);
            }

        }
    };

    EventHandler<MouseEvent> onMouseReleasedEventHandler = new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {

            Node node = (Node) event.getSource();

            moveToSource(node);

            // same for the other cards
            List<Card> list = Game.getSelectedCards( (Card) node);
            for( Card card: list) {
                moveToSource(card);
            }

            // if you find out that the cards are on a valid position, you need to fix it, ie invoke relocate and set the translation to 0
            // fixPosition( node);

        }
    };

    private void moveToSource( Node node) {
        double sourceX = node.getLayoutX() + node.getTranslateX();
        double sourceY = node.getLayoutY() + node.getTranslateY();

        double targetX = node.getLayoutX();
        double targetY = node.getLayoutY();

        Path path = new Path();
        path.getElements().add(new MoveToAbs( node, sourceX, sourceY));
        path.getElements().add(new LineToAbs( node, targetX, targetY));

        PathTransition pathTransition = new PathTransition();
        pathTransition.setDuration(Duration.millis(1000));
        pathTransition.setNode(node);
        pathTransition.setPath(path);
        pathTransition.setCycleCount(1);
        pathTransition.setAutoReverse(true);

        pathTransition.play();
    }

    /**
     * Relocate card to current position and set translate to 0.
     * @param node
     */
    private void fixPosition( Node node) {

        double x = node.getTranslateX();
        double y = node.getTranslateY();

        node.relocate(node.getLayoutX() + x, node.getLayoutY() + y);

        node.setTranslateX(0);
        node.setTranslateY(0);

    }

    class DragContext {

        double x;
        double y;

    }

    // pathtransition works with the center of the node => we need to consider that
    public static class MoveToAbs extends MoveTo {

        public MoveToAbs( Node node, double x, double y) {
            super( x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);

        }

    }

    // pathtransition works with the center of the node => we need to consider that
    public static class LineToAbs extends LineTo {

        public LineToAbs( Node node, double x, double y) {
            super( x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);
        }

    }

}

When you pick a card or a multiple of cards, they'll transition back to their origin.
Here's a screenshot where I dragged the 3rd card from top.

When you check if a card is on a valid destination, you should invoke the fixPosition method. It simply relocates the card, i. e. calculates the position using the translation values, repositions the node and sets its translation to 0.
The tricky part was the PathTransition. It's working from the center of a node, not from the x/y coordinates. Here's a thread regarding that issue to which I replied in case you wish to know more about it.

