Per Henri’s request, here’s the code we are using now. We’re not currently attempting to make this a stand-alone generic component suitable for the Directory, nor has it been tested rigorously.
Note that PageInfo is the simple bean we use in our BeanItemContainer supplied as the source for the Table, having just two properties ‘name’ and ‘pageNumber’.
Here’s all we did:
pageInfoTable = new Table();
pageInfoTable.setWidth(100, UNITS_PERCENTAGE);
pageInfoTable.setSortDisabled(true);
pageInfoTable.setNullSelectionAllowed(true);
pageInfoTable.setDragMode(TableDragMode.ROW);
pageInfoTable.setDropHandler(new DropHandler() {
public void drop(DragAndDropEvent dropEvent) {
DataBoundTransferable t = (DataBoundTransferable)dropEvent.getTransferable();
PageInfo sourceItemId = (PageInfo)t.getItemId(); // returns our Bean
AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) dropEvent.getTargetDetails());
PageInfo targetItemId = (PageInfo)dropData.getItemIdOver(); // returns our Bean
// No move if source and target are the same, or there is no target
if ( sourceItemId == targetItemId || targetItemId == null)
return;
// Let's remove the source of the drag so we can add it back where requested...
pageInfoContainer.removeItem(sourceItemId);
if ( dropData.getDropLocation() == VerticalDropLocation.BOTTOM ) {
pageInfoContainer.addItemAfter(targetItemId,sourceItemId);
} else {
Object prevItemId = pageInfoContainer.prevItemId(targetItemId);
pageInfoContainer.addItemAfter(prevItemId, sourceItemId);
}
}
public AcceptCriterion getAcceptCriterion() {
return new And(new SourceIs(pageInfoTable), AcceptItem.ALL);
}
});
There are some considerations for your needs:
-
What do you do if they drag an item and drop it on the same item (row)? In our case, since we have Beans in the container, we just check if they are the same bean and ignore: sourceItemId == targetItemId
-
What do you do if there is no target (targetItemId == null) for the drop? The sampler put it at the end, but I found I got no target if I dragged to the Table’s column headers, too, so putting it at the end would be odd. I suspect you can do the same by dragging to the bottom of a table (especially if it has a footer).
-
What to do with a drop location of MIDDLE? If the drop location is TOP, it makes sense you want to move the item above the target. If the drop location is BOTTOM, it makes sense you want to move the it above the target. But when it’s MIDDLE (like you drop it right on another item/row), do you put it above or below the target? We chose “before” but are not really happy since we’re not sure what would be considered “standard” for such a thing.
Also, if you drag to the first row in our code, there will be no “prevItemId”, but it appears that the addItemAfter will put it on the top if it’s null.
Also, since our Table is in a Form that can be in EDIT mode or READONLY mode, we have special code for our setReadOnly(boolean readOnly) method so that it works since it’s not an input field like other Form fields, so we only allow it to be selected and/or dragged when in EDIT mode:
pageInfoTable.setReadOnly(readOnly);
pageInfoTable.setSelectable(!readOnly);
pageInfoTable.setDragMode( readOnly ? TableDragMode.NONE : TableDragMode.ROW);
And lastly, when a row/item is selected from our view so that it will then appear in the Form for editing/details, our Form gets called to set a new data source, which we use to then update our pageInfoTable and pageInfoContainer as appropriate. Because there’s no PageInfo beans in our BeanItemContainer (PageInfoContainer) until our Form’s data source is set, we do the following code to set up our page info table accordingly as it otherwise has no properties:
try {
if ( pageInfoContainer != null ) {
pageInfoContainer.removeAllItems();
}
pageInfoContainer = new PageInfoContainer(bean.documentVersion());
pageInfoTablepageInfoTable.setContainerDataSource(pageInfoContainer);
pageInfoList.setVisibleColumns( new String[]{"pageName", "pageNumber"} );
pageInfoTable.setColumnHeaders( new String[]{"Page EsfName", "Order"} );
pageInfoTable.setColumnExpandRatio("pageName", 1);
pageInfoTable.setPageLength(pageInfoContainer.size());
pageInfoTable.setVisible(true);
} catch (Exception e) {
}
Hope this helps someone…or helps us if we’re going about it the wrong way! Thanks…