Hello guys. Today I’ve got some free time to blog. I have made small chemical solution for making these things happen. I was thinking that most of the game developers really need this type of system even more in the content management system also this kind of stuffs are very useful So I’ve planned to blogged about this (Drag n Drop Cell).

Let’s first look over how the things works for the Draggable of list cell.

Drag and Drop Cell in ListView

The above figure is just the concept which I’ve predicted. You can use your own too But in this post I’m doing all stuffs by this algorithm.By the help of that algorithm I’ve made the things sucess.

First let’s start with the custom cell I’ve given that cell name as ListCellX.

/**
 *
 * @author Narayan
 */
public class ListCellX<T> extends ListCell<T> implements ChangeListener<Number>{
    //This attribute is for making my drag n drop totally private
    public static DataFormat dataFormat =  new DataFormat("mycell");
    
    //I keep track of which item is now currently being dragged
    private static IntegerProperty ind = new SimpleIntegerProperty(-1);
    
    //I can hold the dragged item Object for some time.
    private static Object temp = null;
    
    //I'm the item Object keeper. Come to me if you need any item
    private ObservableList items;
    
    //I'm the one who can make things draggable
    private boolean draggable =true; 
    
    //When any cell is dragged then I'm being named which index to be deleted
    private static int toBeDeleted = -1;
    
    //It's my class of fashion
    private String styleclass = "list-cellx";
   
    //I can make things happen
    private void setDraggable(boolean b){
        draggable = b;
    }
    
    //Call me if you want to verify for drag work
    public boolean isDraggable(){
        return draggable;
    }
    
    //Basic mind making I'm adding up to the cell so that
    //those cell can learn how to take place of another cell    
    public void init(ObservableList itms){
            items = itms;
            
            this.indexProperty().addListener(this);
            this.getStyleClass().add(styleclass); 
            //this.setStyle("-fx-background-color : red; ");
    }
    
    
    /**
     * I'm always ready for update 
     * @param item
     * @param empty 
     */
    @Override
    public void updateItem(T item,boolean empty){
        super.updateItem(item, empty); 
        if(item!=null){
            if(getIndex() == ind.get()){
                InnerShadow is = new InnerShadow();
                is.setOffsetX(1.0);
                is.setColor(Color.web("#666666"));
                is.setOffsetY(1.0);                               
                setEffect(is);
            }    
        }
    }
   

    /**
     * If any changes happens for my 'items' I'm watching on you.
     * @param arg0
     * @param arg1
     * @param arg2 
     */
    @Override
    public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
        
        //Wait are you draggable ? and you are on our company?
        if(isDraggable() && getIndex() < items.size()){
                //If some kind of mice will click on your then do this
                setOnMouseClicked(new EventHandler<MouseEvent>(){

                    @Override
                    public void handle(MouseEvent arg0) {
                        getListView().scrollTo(getIndex()); 
                    }   
                    
                });
                //Some body is dragging and they are on me.
                setOnDragEntered(new EventHandler<DragEvent>(){
                    @Override
                    public void handle(DragEvent arg0) {
                        
                        if(arg0.getTransferMode() == TransferMode.MOVE){
                            String cellS = (String)arg0.getDragboard().getContent(dataFormat);
                            
                            Object o = arg0.getDragboard().getContent(dataFormat);
                            if(toBeDeleted == getIndex()){
                                return;
                            }
                            if(toBeDeleted != -1){
                                items.remove(toBeDeleted);
                                toBeDeleted = -1;
                            }
                            if(o != null && temp != null ){
                                if(getIndex() < items.size())                                    
                                    items.add(getIndex(),(T)temp);
                                else if(getIndex() == items.size())
                                    items.add((T)temp);
                                
                            }
                            
                            ind.set(getIndex());
                        }
                    }

                });
                
                //Some body just went off dragging from my cell.
                setOnDragExited(new EventHandler<DragEvent>(){

                    @Override
                    public void handle(DragEvent arg0) {
                       
                        if(arg0.getTransferMode() == TransferMode.MOVE){
                            Object o = arg0.getDragboard().getContent(dataFormat);
                            if(o != null){
                                setEffect(null);                          
                                if(getIndex()<items.size())
                                    toBeDeleted = getIndex();
                                  
                            }
                        }
                    }

                });
               
                //OMG! That mice pressed me. I need to take some action
                pressedProperty().addListener(new ChangeListener<Boolean>(){

                    @Override
                    public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
                        InnerShadow is = new InnerShadow();
                                is.setOffsetX(1.0);
                                is.setColor(Color.web("#666666"));
                                is.setOffsetY(1.0);                               
                        if(!arg2){
							setEffect(null);    
                    }

                });
            
                //Ok I'm off I'm Over stop dragging me man!
                setOnDragOver(new EventHandler<DragEvent>(){
                    @Override
                    public void handle(DragEvent event) {           
                        System.out.println("Over");
                        event.acceptTransferModes(TransferMode.MOVE);                
                    }

                });
                
                //Hey hey hey You are dragging me! Wait I need to call somebody
                setOnDragDetected(new EventHandler<MouseEvent>(){
                        @Override
                        public void handle(MouseEvent event) {
                            
                            Dragboard db = getListView().startDragAndDrop(TransferMode.MOVE);
                            temp = items.get(getIndex());
                            toBeDeleted = getIndex();
                            Object item = items.get(getIndex());
                            /* Put a string on a dragboard */
                            ClipboardContent content = new ClipboardContent();
                            if(item != null)
                                content.put(dataFormat,item.toString());             
                            else
                                content.put(dataFormat,"XData");             
                            db.setContent(content); 
                            event.consume();

                        }

                });

        }
    }
}

FYI I’ve highlighted the codes above. I think you can easily understand the code. I’ve done some commented for codes which could be more clear enough too.

Ok Now After we build our Customized ListCellX we can now easily embed this Cell in our ListView by implementing the cellfactory of specified ListView. You must make sure that you have called the init(ObservableList). A sample work over this cell is given here.

<your listView>.setCellFactory(new Callback<ListView<Person>,ListCell<Person>> (){
	@Override
	public ListCell<Person> call(ListView<Person> arg0) {
		//My cell is on my way to call
		ListCellX<Person> cell = new ListCellX<Person>(){
			@Override
			public void updateItem(Person item,boolean empty){
				super.updateItem(item,empty);
				if(item!=null){   http://blog.ngopal.com.np/?p=1197&preview=true
					//-----------------------
					//I'm making my sexy GUI
					//-----------------------                            
					//Do you stuffs of making your cell sexy
					//finally every thing is just setup
					setGraphic(<your gui>);
				}
			}
		};
		//this is my chemical solution
		//Need to call on every cell for making things work
		cell.init(obj);
		
		//Take my cell
		return cell;
	}

});

In above code sample here we have added our own list cell factory so that that cell knows what we want to do on drag events.

I’ve also made one simple app(Friends List) by using this Facility and one of my best control(AutoFillTextBox). I’ve made that simple app available for you to see if you want.

Friends List Screenshot

I hope you enjoyed reading this post.
Thanks you ! See you coming free days. Have a good day 🙂