4 Replies Latest reply on Apr 2, 2012 7:28 PM by 914170

    ADF Drag and drop event inside the single af:treetable

      Hi Experts,

      I have a af:treeTable in my ADF web project and i would like to implement the drag and drop event to the same tree table for supporting my sample test project use case. Currently i am facing some issue to get the source tree node and the destination tree node of the drop and drop event inside my drop listener method. How can i get those object since i need to perform some business operation inside the listener. Please note that i am not using ADF BC4j in my project. The service layer is implemented as EJB and it's being called from the backing bean.

      Looking forward some guide lines to resolve this issue from you experts.

      Thank you.
        • 1. Re: ADF Drag and drop event inside the single af:treetable
          Frank Nimphius-Oracle

          you use af:dragSource abd af:collectionDropTarget on the same tree. The fact you use non-ADF BC doesn't matter because the drag and drop operation is on the tree, not the business service.

          to get the drop target, identified by the tree path you call

          List dropNodeKey = (List) dropEvent.getDropSite();

          set the current row to the drop node


          You can now access the row data

          JUCtrlHierNodeBinding adfNode = (JUtrlHierNodeData) treeTabe.getRowData();

          For how to read the data from this, see: http://www.oracle.com/technology/products/jdev/tips/fnimphius/getTreeTableSelection/getTreeTableSelection.html

          To get the dragged value:

          Transferable tf = dropEvent.getTransferable();
          DataFlavor<RowKeySet> rksflav = DataFlavor.getDataFlavor(RowKeySet.class, "name provided as the descriminant");
          RowKeySet rks = (RowKeySet) transferable.getData(rksflav);

          //check for null here and then continue ...

          CollectionModel dragModel = transferable.getData(CollectionModel.class);
          JUCtrlHierBinding adfTreeBinding = (JUCtrlHierBinding) dragModel.getWrappedData();

          //below I assume a single selected dragged node. If there are more then iterate over the whole iterator
          List nodeDraggedNodePath = (List) rksflav .iterator().next();

          //... check for nul ... then continue

          JUCtrlHierNodeBinding adfDragNode = (JUCtrlHierNodeBinding ) adfTreeBinding.finNodeByKeyPath(nodeDraggedNodePath);

          //now you have access to the dragged data row in the tree table and follow with http://www.oracle.com/technology/products/jdev/tips/fnimphius/getTreeTableSelection/getTreeTableSelection.html

          • 2. Re: ADF Drag and drop event inside the single af:treetable
            Thanks a lot Frank. I am trying out the suggested way. I have an extended logic ( allow the move as a child if the node object type is A. etc .....) in my drag and drop functionality. So i have done the changes in side the drag and drop listener. Obviously the Tree model is changed and i recreate the model based on the change and then refresh the tree table before return DnDAction.Move (or even DnDAction.none). Unfortunately i am getting the exception. I guess i need to refresh the table after calling the drop listener. How can i do that. Please help me on this.

                 at javax.faces.model.ArrayDataModel.getRowData(ArrayDataModel.java:149)
                 at org.apache.myfaces.trinidad.model.SortableModel.getRowData(SortableModel.java:67)

            How can i refresh the treeTable after the drop Listener execution?

            Looking forward your guide lines.

            Thank you.
            • 3. Re: ADF Drag and drop event inside the single af:treetable
              hi Experts,

              I guess this is due to the sync issue between the datamodel. If i clear the disclosedKeys then it works. However i don't want to clear that because i need to display the collapsed tree.
              Any hits to resolve this issue?

              • 4. Re: ADF Drag and drop event inside the single af:treetable
                It's not a perfect solution, but a work in progress that i'm currently using in my backing bean:

                private RichTree navTree;
                private void exitContainers() {
                boolean success = false;
                while (!success) {
                try {
                } catch (Exception e) {
                success = true;

                private void clearDisclosedRowKeys() {
                if (navTree != null && navTree.getDisclosedRowKeys() != null) {
                RowKeySet rks = navTree.getDisclosedRowKeys();
                Iterator rksIter = rks.iterator();

                while (rksIter.hasNext()) {
                List<Integer> rowkey = (List<Integer>) rksIter.next();
                List<Integer> newRowkey = new ArrayList<Integer>();
                for (Integer row : rowkey) {
                if (navTree.isRowAvailable(row)) {
                } else {
                // Row is no longer available
                if (newRowkey.size() == 0) {
                } else {

                Whenever you make a 'delete' or 'move' in the tree, call clearDisclosedRowKeys(), it will remove anything that's no longer valid, so your tree won't collapse, and you won't get the error anymore.
                I took out my logging and debug statements, but essentially this just gets all the rows, checks to see if they're valid, and if so creates a new RowKeySet with the valid rows in it.

                Of course make sure you have the setNavTree and getNavTree accessor's created and that they're bound in your JSFF, otherwise navTree will always be null.

                I haven't yet found a way to 'nicely' find out if you're at the top level container, so i'm relying on an Exception to occur to give me that information, if anyone knows a better solution please feel free to share it.