Friday, March 16, 2012

JavaFX 2.0: Implement Source and Target of Drag and Drop for Image

In the previous article "JavaFX 2.0: Implement GestureTarget of Drag and Drop for Image", I implement GestureTarget for Image - in form of file.

In this exercise, I TRY to implement both GestureSource and GestureTarget, in form of Image - The image is pass by putImage() and getImage() methods, instead of putFiles() and getFiles().




package javafx_draganddrop_image;

import java.io.File;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.ImageViewBuilder;
import javafx.scene.input.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_DragAndDrop_image extends Application {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("java-buddy.blogspot.com");
        Group root = new Group();
        Scene scene = new Scene(root, 400, 400);
        
        HBox hBox1 = new HBox();
        hBox1.setPrefWidth(400);
        hBox1.setPrefHeight(200);
        hBox1.setStyle("-fx-border-color: red;"
              + "-fx-border-width: 1;"
              + "-fx-border-style: solid;");
      
        HBox hBox2 = new HBox();
        hBox2.setPrefWidth(400);
        hBox2.setPrefHeight(200);
        hBox2.setStyle("-fx-border-color: blue;"
              + "-fx-border-width: 1;"
              + "-fx-border-style: solid;");
        
        insertImage(new Image(getClass().getResourceAsStream("duke_44x80.png")), hBox1);
        insertImage(new Image(getClass().getResourceAsStream("duke_44x80_flip.png")), hBox2);
        
        setupGestureTarget(hBox1);
        setupGestureTarget(hBox2);
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(hBox1, hBox2);
        root.getChildren().addAll(vBox);
        
        primaryStage.setScene(scene);
        primaryStage.show();
        primaryStage.show();
    }
    
    void insertImage(Image i, HBox hb){
        
        ImageView iv = new ImageView();
        iv.setImage(i);
        
        setupGestureSource(iv);
        hb.getChildren().add(iv);
    }
    

    void setupGestureTarget(final HBox targetBox){
        
        targetBox.setOnDragOver(new EventHandler <DragEvent>() {
            @Override
            public void handle(DragEvent event) {

                Dragboard db = event.getDragboard();
                
                if(db.hasImage()){
                    event.acceptTransferModes(TransferMode.COPY);
                }
                
                event.consume();
            }
        });

        targetBox.setOnDragDropped(new EventHandler <DragEvent>() {
            @Override
            public void handle(DragEvent event) {
 
                Dragboard db = event.getDragboard();

                if(db.hasImage()){

                    insertImage(db.getImage(), targetBox);
                    
                    event.setDropCompleted(true);
                }else{
                    event.setDropCompleted(false);
                }

                event.consume();
            }
        });
        
    }
    
    void setupGestureSource(final ImageView source){
        
        source.setOnDragDetected(new EventHandler <MouseEvent>() {
           @Override
           public void handle(MouseEvent event) {
               
               /* allow any transfer mode */
               Dragboard db = source.startDragAndDrop(TransferMode.COPY);
               
               /* put a image on dragboard */
               ClipboardContent content = new ClipboardContent();
               
               Image sourceImage = source.getImage();
               content.putImage(sourceImage);
               db.setContent(content);
               
               event.consume();
           }
       });

    }
}


BUT, THERE IS A BUG:
After draged to copy a Image, then drag the copied Image, "java.lang.IllegalArgumentException: Wrong byte buffer size 44x80 [14080] != 0" will be thrown.
Up to this writing, I have no any solution!

2 comments:

  1. The video shows your example running as I expect! Unfortunately, I've the next problem:

    the ClipboardContent putImage(Image img) function doesn't work for me, it uses to fail with this message: "2013-03-21 14:42:15.351 java[1467:707] 'application/x-java-rawimage' is not a valid UTI string. Cannot set data for an invalid UTI."

    I have no idea why is this happening. I've spend some hours searching on the net about this error and 'UTI' strings, but haven't found a solution yet. Have you experienced that? Any help would be appreciated.

    Thanks in advance!

    ReplyDelete