Hello all,
I am trying to create an example where I have a TilePane with 1..n VBox's inside. I want to be able to permute each one of the VBox's with drag and drop functionality.
I created a ImageBox that extends VBox:
public class ImageBox extends VBox {
ImageView myImageView;
public ImageView imageZone;
public ImageBox() {
this("untitled", null);
}
public ImageBox(final String imageTitle, final Image imageFile) {
this.titleText = imageTitle;
this.image = imageFile;
initImageBox();
}
String titleText;
private Image image;
public String getTitleText() {
return titleText;
}
public void setTitleText(final String titleText) {
this.titleText = titleText;
}
public void initImageBox() {
setId("image-box");
GridPane grid = new GridPane();
grid.setId("image-box-grid");
grid.setHgap(10);
grid.setVgap(10);
// Category in column 0, row 0
Text imageTitle = new Text(titleText);
imageTitle.setFont(Font.font("Arial", FontWeight.BOLD, 12));
grid.add(imageTitle, 1, 0);
// image in column 0-2, row 1
imageZone = new ImageView(image);
grid.add(imageZone, 1, 1);
// Radio button1
Image image1 = new Image(getClass().getResourceAsStream("/images/lock_icon.png"));
RadioButton rb1 = new RadioButton("");
rb1.setGraphic(new ImageView(image1));
grid.add(rb1, 0, 2);
getChildren().add(grid);
setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(final MouseEvent event) {
/* drag was detected, start a drag-and-drop gesture*/
/* allow any transfer mode */
Dragboard db = startDragAndDrop(TransferMode.MOVE);
/* Put a string on a dragboard */
ClipboardContent content = new ClipboardContent();
content.putString(getTitleText());
db.setContent(content);
event.consume();
}
});
setOnDragOver(new EventHandler<DragEvent>() {
public void handle(final DragEvent event) {
/* data is dragged over the target */
/* accept it only if it is not dragged from the same node
* and if it has a string data */
if (event.getGestureSource() != this && event.getDragboard().hasString()) {
/* allow for both copying and moving, whatever user chooses */
event.acceptTransferModes(TransferMode.MOVE);
}
System.out.println("Dragging image:" + getTitleText());
event.consume();
}
});
setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(final DragEvent event) {
/* data dropped */
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
// setTitleText("I must go to index 0");
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
});
setOnDragDone(new EventHandler<DragEvent>() {
public void handle(final DragEvent event) {
/* the drag and drop gesture ended */
/* if the data was successfully moved, clear it */
if (event.getTransferMode() == TransferMode.MOVE) {
setTitleText(getTitleText());
}
event.consume();
}
});
}
Next in my TestTilePaneDND I have:
final TilePane imageTilePane = new TilePane();
imageTilePane.setVgap(10);
imageTilePane.setHgap(10);
// Initialize a new image box with a new name and image
final Image imageFile = new Image(PhotographerScreen.class.getResourceAsStream("/images/null.png"));
for (int i = 0; i < numberOfImageBoxs; i++) {
ImageBox imageBox = new ImageBox("Picture nr" + i, imageFile);
imageTilePane.getChildren().add(imageBox);
}
With this code I have all the ImageBox's lined out inside the TilePane, but when I drag one to another the content is not transferred. Maybe I have to add and remove nodes from the tilePane each time I do a drag and drop.
Can I say that each of my VBox (ImageBox) is a source and also a target where the tiles can be dropped?
Does anyone think this might be a good approach?
Thanks and best regards.
António