Sun. Jan 17th, 2021

Explanation: The ADF Faces framework provides the ability to drag and drop items from one place to another on a page.

When users click on a source and begin to drag, the browser displays the element being dragged as a ghost element attached to the mouse pointer. Once the ghost element hovers over a valid target, the target component shows some feedback (for example, it becomes highlighted). If the user drags the ghost element over an invalid target, the cursor changes to indicate that the target is not valid.

When dragging attribute values, the user can only copy the value to the target. For all other drag and drop scenarios, on the drop, the element can be copied (copy and paste), moved (cut and paste), or linked (copy and paste as a link, for example, copying text and pasting the text as an actual URL).

The component that will be dragged and that contains the value is called the source. The component that will accept the drop is called the target. We use a specific tag as a child to the source and target components that tells the framework to allow the drop.

Drag and drop functionality is not supported between windows. Any drag that extends past the window boundaries will be canceled. Drag and drop functionality is supported between popup windows and the base page for the popup.

Also note that drag and drop functionality is not accessible; that is, there are no keyboard strokes that can be used to execute a drag and drop. Therefore, if our application requires all functionality to be accessible, we must provide this logic. For example, our page might also present users with a method for selecting objects and a Move button or menu item that allows them to move those selected objects.

Requirement: I have a demo.jspx page. On that page I have two sections:Right section and Left section. In the Right section I will have four components: Chop Vegetables, Cook Vegetable, Eat Cooked Vegetables, and Navigation.

I the Left section I will be dropping the components by dragging the components from the Right section. On drag of the components from the Right section on the Left section it should create those components in the Left section.

Also if I try to drag and drop components that are already in the screen it will not allow us to do so instead it will give us the message saying that the component is already added in the panelDashBoard. Only Navigation is allowed two time in the panelDashBoard.

Solution: For solution to the above requirement follow the steps as shown below:

Step 1: Create an Oracle ADF Fusion Web Application and name the application as DragDropDemo.

Step 2: Create a dragDropBTF bounded task flow. Drag and drop view inside the dragDropBTF.xml. Name the view as dragDrop and double click on the dragDrop view to create a dragDrop.jsff fragments. It should be based on JSP XML.

Now, create a demo.jspx page and drag and drop dragDropBTF.xml inside the demo.jspx page as a region.

Step 3: Open dragDrop.jsff fragments. Drag and drop af:panelStretchLayout from the component palette. Keep the center f:facet and delete all other f:facet. Set the styleClass of the af:panelStretchLayout  as styleClass=”AFStretchWidth”

Drag and drop af:panelGridLayout inside the center facet. The af:panelGridLayout will have one row with two columns.

Inside the first af:gridCell drag and drop af:panelGroupLayout. Make the af:panelGroupLayout layout=”vertical“. Inside the af:panelGroupLayout drag and drop four af:button. Name the af:button as: Chop Vegetables, Cook Vegetables, Eat Cook Vegetables, and Navigation.

Inside the second af:gridCell drag and drop af:panelGroupLayout. Make the af:panelGroupLayout properties as layout=”horizontal” inlineStyle=”width:1000px;”. Inside the af:panelGroupLayout drag and drop af:panelDashboard. Set the properties of the af:panelDashboard  as inlineStyle=”background-color:Scrollbar;” styleClass=”AFStretchWidth” dimensionsFrom=”parent” columns=”5″.

Step 4: Drag and drop af:componentDragSource inside the  Chop Vegetables button.

Step 5: Go to the af:panelDashboard. Create the dropListener as dropListener= “#{pageFlowScope.MyyBean.handleDnd}”. 

Set the af:dataFlavor class as af:dataFlavor flavorClass= “java.lang.Object”. The will enable the af:panelDashboard to be dropable.

Create the binding of the af:panelDashboard as binding=”#{pageFlowScope.AdminBean.dandPNLDB}”.

Thus, the complete dragDrop.jsff code is shown below:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
          xmlns:f="http://java.sun.com/jsf/core">
    <af:panelStretchLayout id="psl1" styleClass="AFStretchWidth">
        <f:facet name="center">
            <af:panelGridLayout id="pgl1">
                <af:gridRow marginTop="5px" height="auto" marginBottom="5px" id="gr1">
                    <af:gridCell marginStart="5px" width="180px" marginEnd="5px" id="gc2">
                        <af:panelGroupLayout id="pgl2" layout="vertical">
                            <af:commandButton text="Chop Vegetables" id="b1"
                                              inlineStyle="font-weight:bold; color:Black; height:40px; width:160px;">
                                <af:componentDragSource/>
                            </af:commandButton>
                            <af:commandButton text="Cook Vegetables" id="b2"
                                              inlineStyle="font-weight:bold; color:Black; height:40px; width:160px;">
                                <af:componentDragSource/>
                            </af:commandButton>
                            <af:commandButton text="Eat Cook Vegetables" id="b3"
                                              inlineStyle="font-weight:bold; color:Black;height:40px; width:160px;">
                                <af:componentDragSource/>
                            </af:commandButton>
                            <af:commandButton text="Navigation" id="b4"
                                              inlineStyle="font-weight:bold; color:Black;height:40px; width:160px;">
                                <af:componentDragSource/>
                            </af:commandButton>
                        </af:panelGroupLayout>
                    </af:gridCell>
                    <af:gridCell marginStart="5px" width="100%" id="gc1">
                        <af:panelGroupLayout id="pgl3" layout="horizontal" inlineStyle="width:1000px;">
                            <af:panelDashboard id="pd1" inlineStyle="background-color:InfoBackground;"
                                               styleClass="AFStretchWidth" dimensionsFrom="parent" columns="5"
                                               dropListener="#{pageFlowScope.MyyBean.handleDnd}"
                                               binding="#{pageFlowScope.MyyBean.dandPNLDB}">
                                <af:dataFlavor flavorClass="java.lang.Object"/>
                            </af:panelDashboard>
                        </af:panelGroupLayout>
                    </af:gridCell>
                </af:gridRow>
            </af:panelGridLayout>
        </f:facet>
    </af:panelStretchLayout>
</jsp:root>

Step 6: Now go to the MyBean.java class and write the code for the handleContainerDrag method.

package com.susanto;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import oracle.adf.view.rich.component.rich.layout.RichPanelDashboard;
import oracle.adf.view.rich.component.rich.layout.RichPanelGroupLayout;
import oracle.adf.view.rich.component.rich.nav.RichCommandButton;
import oracle.adf.view.rich.component.rich.output.RichImage;
import oracle.adf.view.rich.context.AdfFacesContext;
import oracle.adf.view.rich.datatransfer.DataFlavor;
import oracle.adf.view.rich.datatransfer.Transferable;
import oracle.adf.view.rich.dnd.DnDAction;
import oracle.adf.view.rich.dnd.DragSource;
import oracle.adf.view.rich.event.ClientListenerSet;
import oracle.adf.view.rich.event.DropEvent;

public class MyyBean {
    private RichPanelDashboard dandPNLDB;

    public MyyBean() {
    }

    public DnDAction handleDnd(DropEvent dropEvent) {
        Transferable dropTransferable = dropEvent.getTransferable();
        UIComponent dropComponent = dropEvent.getDropComponent();
        UIComponent movedComponent = dropTransferable.getData(DataFlavor.UICOMPONENT_FLAVOR);
        UIComponent componentToAdd = null;
        boolean isMove;
        isMove = movedComponent.getParent().equals(dropComponent);
        if (!isMove)
            componentToAdd = buildComponent(movedComponent);
        else
            componentToAdd = movedComponent;
        ClientListenerSet clientListenerSet = new ClientListenerSet();
        clientListenerSet.addBehavior("new AdfInitializationBehavior('component.setDragSource(new AdfComponentDragSource())')");
        DragSource ds = new DragSource(DnDAction.MOVE_ONLY);
        componentToAdd.getAttributes().put("_dragSource", ds);
        ((RichPanelGroupLayout) componentToAdd).setClientListeners(clientListenerSet);
        if (isMove)
            dropComponent.getChildren().remove(componentToAdd);
        dropComponent.getChildren().add(dropEvent.getDropSiteIndex(), componentToAdd);
        AdfFacesContext.getCurrentInstance().addPartialTarget(dropComponent);
        return DnDAction.NONE;
    }

    private UIComponent buildComponent(UIComponent movedComponent) {
        UIComponent componentToAdd = null;
        if (movedComponent instanceof RichCommandButton) {
            int childrenCount = this.getDandPNLDB().getChildCount();
            List<UIComponent> presentComponents = dandPNLDB.getChildren();
            ArrayList<String> al = new ArrayList<String>();
            for (UIComponent uicomponent : presentComponents) {
                String componentId = uicomponent.getId().toString();
                al.add(componentId);
            }
            if (movedComponent.getId().equals("b1")) {
                if (al.contains("chopVegetable1")) {
                    FacesMessage infoMessage = new FacesMessage("Chop Vegetable is already in the workflow");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    RichCommandButton cb = new RichCommandButton();

                    cb.setId("d001");
                    cb.setInlineStyle("height:40px; width:160px; text-align:center;border-left-style:solid; border-left-width:2px; border-left-color:Olive; border-right-color:Olive; border-right-style:solid; border-right-width:2px; border-top-color:Olive; border-top-style:solid; border-top-width:2px; border-bottom-color:Olive; border-bottom-style:solid; border-bottom-width:2px;");
                    cb.setText("Chop Vegetables");
                    componentToAdd = cb;
                }
            }
            if (movedComponent.getId().equals("b2")) {
                if (al.contains("cookVegetables")) {
                    FacesMessage infoMessage = new FacesMessage("Cook Vegetable is already in the workflow");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    RichCommandButton cb = new RichCommandButton();
                    cb.setId("t001");
                    cb.setInlineStyle("height:40px; width:160px; text-align:center; border-left-style:solid; border-left-width:2px; border-left-color:Olive; border-right-color:Olive; border-right-style:solid; border-right-width:2px; border-top-color:Olive; border-top-style:solid; border-top-width:2px; border-bottom-color:Olive; border-bottom-style:solid; border-bottom-width:2px;");
                    cb.setText("Cook Vegetables");
                    componentToAdd = cb;
                }
            }
            if (movedComponent.getId().equals("b3")) {
                if (al.contains("eatCookVegetables")) {
                    FacesMessage infoMessage = new FacesMessage("Eat Cook Vegetable is already in the workflow");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    RichCommandButton cb = new RichCommandButton();
                    cb.setId("p001");
                    cb.setInlineStyle("height:40px; width:160px; text-align:center; border-left-style:solid; border-left-width:2px; border-left-color:Olive; border-right-color:Olive; border-right-style:solid; border-right-width:2px; border-top-color:Olive; border-top-style:solid; border-top-width:2px; border-bottom-color:Olive; border-bottom-style:solid; border-bottom-width:2px;");
                    cb.setText("Eat Cook Vegetables");
                    componentToAdd = cb;
                }
            }

            if (movedComponent.getId().equals("b4")) {
                if (al.contains("arrow1") && al.contains("arrow2")) {
                    FacesMessage infoMessage = new FacesMessage("Cannot add more navigation component");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    int noofarr = 1;
                    int i;
                    int childCount = this.getDandPNLDB().getChildCount();
                    List<UIComponent> containing = dandPNLDB.getChildren();
                    ArrayList<String> all = new ArrayList<String>();
                    for (UIComponent uicomponent : presentComponents) {
                        String componentId = uicomponent.getId().toString();
                        all.add(componentId);
                    }
                    if (all.contains("chopVegetable1"))
                        all.remove("chopVegetable1");
                    if (all.contains("cookVegetables"))
                        all.remove("cookVegetables");
                    if (all.contains("eatCookVegetables"))
                        all.remove("eatCookVegetables");

                    for (i = 0; i < all.size(); ++i) {
                        if (all.get(i).contains("arr")) {
                        }
                    }
                    noofarr = noofarr + i;
                    RichImage cb = new RichImage();
                    cb.setId("arr" + noofarr);
                    cb.setSource("/images/forwardArrow.png");
                    componentToAdd = cb;
                }
            }

        }
        RichPanelGroupLayout pgl = new RichPanelGroupLayout();

        if (componentToAdd.getId().equals("d001")) {
            pgl.setId("chopVegetable1");
        }
        if (componentToAdd.getId().equals("t001"))
            pgl.setId("cookVegetables");
        if (componentToAdd.getId().equals("p001"))
            pgl.setId("eatCookVegetables");
        if (componentToAdd.getId().equals("arr1")) {
            pgl.setId("arrow1");
        }
        if (componentToAdd.getId().equals("arr2")) {
            pgl.setId("arrow2");
        }

        pgl.getChildren().add(componentToAdd);
        return pgl;
    }

    public void setDandPNLDB(RichPanelDashboard dandPNLDB) {
        this.dandPNLDB = dandPNLDB;
    }

    public RichPanelDashboard getDandPNLDB() {
        return dandPNLDB;
    }
}

Step 7: Save all and run the application. Thus the ran application is shown below:

Now drag and drop Chop Vegetables in the Yellow region that is the af:panelDashBoard. Similarly drag drop the other components that is Cook Vegatables, Eat Cook Vegetables, and Navigation and we can see that the component gets created as shown below:

Now if we try to drag and drop the components that are already in the panelDashBoard, then it will not allow us to do so. It will give us the below message:

Similarly, if we try to drag and drop more than two navigation it will also not allow us and will show us the below message.

Hence, the drag and drop functioanlity to create component is solved.

Step 8: Next requirement is to drag and delete components. For this we will put an af:image in the dragDrop.jsff fragment. Initially this image will be an recycle_empty.png. When we drag and drop some components inside this recycle_empty.png the image get changed into recycle_filled.png which will signified that the component is deleted and it is in the bin now. Also the component gets deleted from the panelDashBoard.

For this we will have two images: recycle_empty.png and recycle_filled.png as shown below:

recycle_empty.png
recycle_filled.png

Drag and drop af:panelGroupLayout after af:commandButton with id =“b4“. Set the property of the af:panelGroupLayout as halign=”center” layout=”vertical”. Also create the binding of the af:panelGroupLayout as binding=”#{pageFlowScope.MyyBean.pglPollListenerContainerBinding}”. This will help us to refresh the parent of the af:image.

Drag and drop af:poll inside the af:panelGroupLayout. This will allow us to refresh the component after certain interval of time. Set the interval fo the af:poll as interval=”2000″ , create the pollListener  as pollListener=”#{pageFlowScope.AdminBean.pollListenerRecycleBin}”. Initially set rendered=”false”. Also create the binding of the af:poll as binding=”#{pageFlowScope.AdminBean.pollListenerRecycleBinBinding}”.

Now drag and drop af:image inside the af:panelGroupLayout and set the properties of the af:image as shortDesc=”emptyBin”                                                               inlineStyle=”width:55px; height:59px;” source=”#{resource[‘images:recycle_empty.png’]}”  binding=”#{pageFlowScope.AdminBean.recycleBinding}”.

Drag and drop af:dropTarget inside the af:image. Set actions=”MOVE” and create dropListener  as dropListener=”#{pageFlowScope.AdminBean.deleteHandler}”.

Set the af:dataFlavor class as flavorClass=”java.lang.Object”.

Thus, the newly added components in dragDrop.jsff are shown below:

<panelGroupLayout id="pgl4" halign="center" layout="vertical"
                  binding="#{pageFlowScope.MyyBean.pglPollListenerContainerBinding}">
    <poll id="p1" interval="2000" pollListener="#{pageFlowScope.MyyBean.pollListenerRecycleBin}" rendered="false"
          binding="#{pageFlowScope.MyyBean.pollListenerRecycleBinBinding}"/>
    <image source="#{resource['images:recycle_empty.png']}" id="i1" shortDesc="emptyBin"
           inlineStyle="width:55px; height:59px;" binding="#{pageFlowScope.MyyBean.recycleBinding}">
        <dropTarget dropListener="#{pageFlowScope.MyyBean.deleteHandler}" actions="MOVE">
            <dataFlavor flavorClass="java.lang.Object"/>
        </dropTarget>
    </image>
</panelGroupLayout>

Step 9: Now write the code for the deleteHandler method in the MyBean.java class as shown below:

    public DnDAction deleteHandler(DropEvent dropEvent) {
        this.pollListenerRecycleBinBinding.setRendered(true);
        Transferable transferable = dropEvent.getTransferable();
        UIComponent dragComponent = null;
        dragComponent = transferable.getData(DataFlavor.UICOMPONENT_FLAVOR);
        List<UIComponent> addedComponents = dandPNLDB.getChildren();
        ArrayList<String> al = new ArrayList<String>();
        for (UIComponent uicomponent : addedComponents) {
            String componentId = uicomponent.getId().toString();
            al.add(componentId);
        }
        for (UIComponent uicomponent : addedComponents) {
            if (dragComponent.getId().equalsIgnoreCase("chopVegetable1")) {
                int aa = al.indexOf("chopVegetable1");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");

            } else if (dragComponent.getId().equalsIgnoreCase("cookVegetables")) {
                int aa = al.indexOf("cookVegetables");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");

            } else if (dragComponent.getId().equalsIgnoreCase("eatCookVegetables")) {
                int aa = al.indexOf("eatCookVegetables");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");
            } else if (dragComponent.getId().equalsIgnoreCase("arrow1")) {
                int aa = al.indexOf("arrow1");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");
            } else if (dragComponent.getId().equalsIgnoreCase("arrow2")) {
                int aa = al.indexOf("arrow2");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");
            }
            break;
        }
        AdfFacesContext.getCurrentInstance().addPartialTarget(pglPollListenerContainerBinding);
        AdfFacesContext.getCurrentInstance().addPartialTarget(recycleBinding);
        AdfFacesContext.getCurrentInstance().addPartialTarget(dandPNLDB);
        return DnDAction.NONE;
    }

Step 10: Now, write the code for the pollListenerRecycleBin in MyBean.java class as shown below:

    public void pollListenerRecycleBin(PollEvent pollEvent) {
        System.out.println("pollListenerRecycleBin started");
        recycleBinding.setSource("/images/recycle_empty.png");
        AdfFacesContext.getCurrentInstance().addPartialTarget(recycleBinding);
        System.out.println("pollListenerRecycleBin ended");
        this.pollListenerRecycleBinBinding.setRendered(false);
        AdfFacesContext.getCurrentInstance().addPartialTarget(pglPollListenerContainerBinding);
    }

Step 11: Thus, the complete dragDrop.jsff code is shown below:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
          xmlns:f="http://java.sun.com/jsf/core">
    <af:panelStretchLayout id="psl1" styleClass="AFStretchWidth">
        <f:facet name="center">
            <af:panelGridLayout id="pgl1">
                <af:gridRow marginTop="5px" height="auto" marginBottom="5px" id="gr1">
                    <af:gridCell marginStart="5px" width="180px" marginEnd="5px" id="gc2">
                        <af:panelGroupLayout id="pgl2" layout="vertical">
                            <af:commandButton text="Chop Vegetables" id="b1"
                                              inlineStyle="font-weight:bold; color:Black; height:40px; width:160px; ">
                                <af:componentDragSource/>
                            </af:commandButton>
                            <af:commandButton text="Cook Vegetables" id="b2"
                                              inlineStyle="font-weight:bold; color:Black; height:40px; width:160px; ">
                                <af:componentDragSource/>
                            </af:commandButton>
                            <af:commandButton text="Eat Cook Vegetables" id="b3"
                                              inlineStyle="font-weight:bold; color:Black;height:40px; width:160px; ">
                                <af:componentDragSource/>
                            </af:commandButton>
                            <af:commandButton text="Navigation" id="b4"
                                              inlineStyle="font-weight:bold; color:Black;height:40px; width:160px; ">
                                <af:componentDragSource/>
                            </af:commandButton>
                            <af:panelGroupLayout id="pgl4" halign="center" layout="vertical"
                                                 binding="#{pageFlowScope.MyyBean.pglPollListenerContainerBinding}">
                                <af:poll id="p1" interval="2000"
                                         pollListener="#{pageFlowScope.MyyBean.pollListenerRecycleBin}" rendered="false"
                                         binding="#{pageFlowScope.MyyBean.pollListenerRecycleBinBinding}"/>
                                <af:image source="#{resource['images:recycle_empty.png']}" id="i1" shortDesc="emptyBin"
                                          inlineStyle="width:55px; height:59px;"
                                          binding="#{pageFlowScope.MyyBean.recycleBinding}">
                                    <af:dropTarget dropListener="#{pageFlowScope.MyyBean.deleteHandler}" actions="MOVE">
                                        <af:dataFlavor flavorClass="java.lang.Object"/>
                                    </af:dropTarget>
                                </af:image>
                            </af:panelGroupLayout>
                        </af:panelGroupLayout>
                    </af:gridCell>
                    <af:gridCell marginStart="5px" width="100%" id="gc1">
                        <af:panelGroupLayout id="pgl3" layout="horizontal" inlineStyle="width:1000px;">
                            <af:panelDashboard id="pd1" inlineStyle="background-color:InfoBackground;"
                                               styleClass="AFStretchWidth" dimensionsFrom="parent" columns="5"
                                               dropListener="#{pageFlowScope.MyyBean.handleDnd}"
                                               binding="#{pageFlowScope.MyyBean.dandPNLDB}">
                                <af:dataFlavor flavorClass="java.lang.Object"/>
                            </af:panelDashboard>
                        </af:panelGroupLayout>
                    </af:gridCell>
                </af:gridRow>
            </af:panelGridLayout>
        </f:facet>
    </af:panelStretchLayout>
</jsp:root>

Step 12: Thus, the complete MyBean.java class code is shown below:

package com.susanto;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import oracle.adf.view.rich.component.rich.RichPoll;
import oracle.adf.view.rich.component.rich.layout.RichPanelDashboard;
import oracle.adf.view.rich.component.rich.layout.RichPanelGroupLayout;
import oracle.adf.view.rich.component.rich.nav.RichCommandButton;
import oracle.adf.view.rich.component.rich.output.RichImage;
import oracle.adf.view.rich.context.AdfFacesContext;
import oracle.adf.view.rich.datatransfer.DataFlavor;
import oracle.adf.view.rich.datatransfer.Transferable;
import oracle.adf.view.rich.dnd.DnDAction;
import oracle.adf.view.rich.dnd.DragSource;
import oracle.adf.view.rich.event.ClientListenerSet;
import oracle.adf.view.rich.event.DropEvent;

import org.apache.myfaces.trinidad.event.PollEvent;

public class MyyBean {
    private RichPanelDashboard dandPNLDB;
    private RichPanelGroupLayout pglPollListenerContainerBinding;
    private RichPoll pollListenerRecycleBinBinding;
    private RichImage recycleBinding;

    public MyyBean() {
    }

    public DnDAction handleDnd(DropEvent dropEvent) {
        Transferable dropTransferable = dropEvent.getTransferable();
        UIComponent dropComponent = dropEvent.getDropComponent();
        UIComponent movedComponent = dropTransferable.getData(DataFlavor.UICOMPONENT_FLAVOR);
        UIComponent componentToAdd = null;
        boolean isMove;
        isMove = movedComponent.getParent().equals(dropComponent);
        if (!isMove)
            componentToAdd = buildComponent(movedComponent);
        else
            componentToAdd = movedComponent;
        ClientListenerSet clientListenerSet = new ClientListenerSet();
        clientListenerSet.addBehavior("new AdfInitializationBehavior('component.setDragSource(new AdfComponentDragSource())')");
        DragSource ds = new DragSource(DnDAction.MOVE_ONLY);
        componentToAdd.getAttributes().put("_dragSource", ds);
        ((RichPanelGroupLayout) componentToAdd).setClientListeners(clientListenerSet);
        if (isMove)
            dropComponent.getChildren().remove(componentToAdd);
        dropComponent.getChildren().add(dropEvent.getDropSiteIndex(), componentToAdd);
        AdfFacesContext.getCurrentInstance().addPartialTarget(dropComponent);
        return DnDAction.NONE;
    }

    private UIComponent buildComponent(UIComponent movedComponent) {
        UIComponent componentToAdd = null;
        if (movedComponent instanceof RichCommandButton) {
            int childrenCount = this.getDandPNLDB().getChildCount();

            List<UIComponent> presentComponents = dandPNLDB.getChildren();
            ArrayList<String> al = new ArrayList<String>();
            for (UIComponent uicomponent : presentComponents) {
                String componentId = uicomponent.getId().toString();
                al.add(componentId);
            }
            if (movedComponent.getId().equals("b1")) {
                if (al.contains("chopVegetable1")) {
                    FacesMessage infoMessage = new FacesMessage("Chop Vegetable is already in the workflow");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    RichCommandButton cb = new RichCommandButton();

                    cb.setId("d001");
                    cb.setInlineStyle("height:40px; width:160px; text-align:center;border-left-style:solid; border-left-width:2px; border-left-color:Olive; border-right-color:Olive; border-right-style:solid; border-right-width:2px; border-top-color:Olive; border-top-style:solid; border-top-width:2px; border-bottom-color:Olive; border-bottom-style:solid; border-bottom-width:2px;");
                    cb.setText("Chop Vegetables");
                    componentToAdd = cb;
                }
            }
            if (movedComponent.getId().equals("b2")) {
                if (al.contains("cookVegetables")) {
                    FacesMessage infoMessage = new FacesMessage("Cook Vegetable is already in the workflow");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    RichCommandButton cb = new RichCommandButton();
                    cb.setId("t001");
                    cb.setInlineStyle("height:40px; width:160px; text-align:center; border-left-style:solid; border-left-width:2px; border-left-color:Olive; border-right-color:Olive; border-right-style:solid; border-right-width:2px; border-top-color:Olive; border-top-style:solid; border-top-width:2px; border-bottom-color:Olive; border-bottom-style:solid; border-bottom-width:2px;");
                    cb.setText("Cook Vegetables");
                    componentToAdd = cb;
                }
            }
            if (movedComponent.getId().equals("b3")) {
                if (al.contains("eatCookVegetables")) {
                    FacesMessage infoMessage = new FacesMessage("Eat Cook Vegetable is already in the workflow");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    RichCommandButton cb = new RichCommandButton();
                    cb.setId("p001");
                    cb.setInlineStyle("height:40px; width:160px; text-align:center; border-left-style:solid; border-left-width:2px; border-left-color:Olive; border-right-color:Olive; border-right-style:solid; border-right-width:2px; border-top-color:Olive; border-top-style:solid; border-top-width:2px; border-bottom-color:Olive; border-bottom-style:solid; border-bottom-width:2px;");
                    cb.setText("Eat Cook Vegetables");
                    componentToAdd = cb;
                }
            }

            if (movedComponent.getId().equals("b4")) {
                if (al.contains("arrow1") && al.contains("arrow2")) {
                    FacesMessage infoMessage = new FacesMessage("Cannot add more navigation component");
                    infoMessage.setSeverity(FacesMessage.SEVERITY_INFO);
                    FacesContext.getCurrentInstance().addMessage(null, infoMessage);
                } else {
                    int noofarr = 1;
                    int i;
                    int childCount = this.getDandPNLDB().getChildCount();
                    List<UIComponent> containing = dandPNLDB.getChildren();
                    ArrayList<String> all = new ArrayList<String>();
                    for (UIComponent uicomponent : presentComponents) {
                        String componentId = uicomponent.getId().toString();
                        all.add(componentId);
                    }
                    if (all.contains("chopVegetable1"))
                        all.remove("chopVegetable1");
                    if (all.contains("cookVegetables"))
                        all.remove("cookVegetables");
                    if (all.contains("eatCookVegetables"))
                        all.remove("eatCookVegetables");
                    for (i = 0; i < all.size(); ++i) {
                        if (all.get(i).contains("arr")) {
                        }
                    }
                    noofarr = noofarr + i;
                    RichImage cb = new RichImage();
                    cb.setId("arr" + noofarr);
                    cb.setSource("/images/forwardArrow.png");
                    componentToAdd = cb;
                }
            }

        }
        RichPanelGroupLayout pgl = new RichPanelGroupLayout();

        if (componentToAdd.getId().equals("d001")) {
            pgl.setId("chopVegetable1");
        }
        if (componentToAdd.getId().equals("t001"))
            pgl.setId("cookVegetables");
        if (componentToAdd.getId().equals("p001"))
            pgl.setId("eatCookVegetables");
        if (componentToAdd.getId().equals("arr1")) {
            pgl.setId("arrow1");
        }
        if (componentToAdd.getId().equals("arr2")) {
            pgl.setId("arrow2");
        }

        pgl.getChildren().add(componentToAdd);
        return pgl;
    }

    public DnDAction deleteHandler(DropEvent dropEvent) {
        this.pollListenerRecycleBinBinding.setRendered(true);
        Transferable transferable = dropEvent.getTransferable();
        UIComponent dragComponent = null;
        dragComponent = transferable.getData(DataFlavor.UICOMPONENT_FLAVOR);
        List<UIComponent> addedComponents = dandPNLDB.getChildren();

        ArrayList<String> al = new ArrayList<String>();
        for (UIComponent uicomponent : addedComponents) {
            String componentId = uicomponent.getId().toString();
            al.add(componentId);
        }
        for (UIComponent uicomponent : addedComponents) {
            if (dragComponent.getId().equalsIgnoreCase("chopVegetable1")) {
                int aa = al.indexOf("chopVegetable1");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");

            } else if (dragComponent.getId().equalsIgnoreCase("cookVegetables")) {
                int aa = al.indexOf("cookVegetables");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");

            } else if (dragComponent.getId().equalsIgnoreCase("eatCookVegetables")) {
                int aa = al.indexOf("eatCookVegetables");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");
            } else if (dragComponent.getId().equalsIgnoreCase("arrow1")) {
                int aa = al.indexOf("arrow1");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");
            } else if (dragComponent.getId().equalsIgnoreCase("arrow2")) {
                int aa = al.indexOf("arrow2");
                addedComponents.remove(aa);
                recycleBinding.setSource("/images/recycle_filled.png");
            }
            break;
        }
        AdfFacesContext.getCurrentInstance().addPartialTarget(pglPollListenerContainerBinding);
        AdfFacesContext.getCurrentInstance().addPartialTarget(recycleBinding);
        AdfFacesContext.getCurrentInstance().addPartialTarget(dandPNLDB);
        return DnDAction.NONE;
    }

    public void pollListenerRecycleBin(PollEvent pollEvent) {
        System.out.println("pollListenerRecycleBin started");
        recycleBinding.setSource("/images/recycle_empty.png");

        AdfFacesContext.getCurrentInstance().addPartialTarget(recycleBinding);
        System.out.println("pollListenerRecycleBin ended");
        this.pollListenerRecycleBinBinding.setRendered(false);
        AdfFacesContext.getCurrentInstance().addPartialTarget(pglPollListenerContainerBinding);
    }

    public void setDandPNLDB(RichPanelDashboard dandPNLDB) {
        this.dandPNLDB = dandPNLDB;
    }

    public RichPanelDashboard getDandPNLDB() {
        return dandPNLDB;
    }

    public void setPglPollListenerContainerBinding(RichPanelGroupLayout pglPollListenerContainerBinding) {
        this.pglPollListenerContainerBinding = pglPollListenerContainerBinding;
    }

    public RichPanelGroupLayout getPglPollListenerContainerBinding() {
        return pglPollListenerContainerBinding;
    }

    public void setPollListenerRecycleBinBinding(RichPoll pollListenerRecycleBinBinding) {
        this.pollListenerRecycleBinBinding = pollListenerRecycleBinBinding;
    }

    public RichPoll getPollListenerRecycleBinBinding() {
        return pollListenerRecycleBinBinding;
    }

    public void setRecycleBinding(RichImage recycleBinding) {
        this.recycleBinding = recycleBinding;
    }

    public RichImage getRecycleBinding() {
        return recycleBinding;
    }
}

Step 13: Save all and run the application. The ran application is shown below:

Now, we will drag and drop components in the panelDashBoard that is the yellow region to create some components as shown below:

Now we will drag and drop newly created components inside the recycle_empty.png image to delete the newly created compoenents.

Select Eat Cook Vegetables from the newly created components and drag and drop it inside the recycle_empty.png image as shown below and release.

Thus, the Eat Cook Vegetable component gets deleted as shown below:

Now we can notice that after two seconds the recycle_filled.png image get changed to recycle_empty.png as shown below. Here, the source of the image gets change after two seconds.

Hence, the solution to our requirement.

If you like the post please comment, share, and do join me on Facebook. Please subscribe to my YouTube Channel for video tutorials.

Thanks & Regards,
Susanto Paul

 231 total views,  1 views today

By Susanto Paul

Susanto is an Oracle ACE, a qualified MCA, MBA, and a highly-skilled Senior Oracle Specialist. He is an enthusiastic Blogger and YouTuber who helps learners to solve their complex problems more efficiently. He has 9+ years of experience in multiple technologies like AWS, Oracle ADF, Oracle APEX, Oracle JET, Oracle VBCS, Oracle IDCS, Oracle PL/SQL, Oracle Integration Cloud, Java, JDBC, Servlets, JSP, Spring, Hibernate, HTML5, CSS3, JavaScript, TypeScript, NodesJS, Angular, MySQL, Oracle WebLogic Server, JUnit, JMeter, Selenium Web Driver, etc. He is a certified: Oracle Certified Professional Java SE 6 Programmer, Oracle ADF 11g Certified Implementation Specialist, Oracle Cloud Platform Application Integration 2020 Certified Specialist, Oracle Cloud Infrastructure Foundations 2020 Certified Associate, and Oracle Cloud Infrastructure Developer 2020 Certified Associate

Leave a Reply

Your email address will not be published. Required fields are marked *