Hi… everyone.
I’ve placed tree into panel (with scrolling).
If scrolling all the way down and clicking on any item, the scrollbar jumps back to the middle.
I’ve noticed that this bug has something to do with ItemClickListener which I have added.
The simplest example is taking “Drag items between tree and table” sample code, putting the tree into some scrollable panel
and adding an ItemClickListener to the tree:
/**
- Created by IntelliJ IDEA.
- User: eligo
- Date: 4/13/11
- Time: 10:17 AM
- To change this template use File | Settings | File Templates.
*/
import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.event.dd.acceptcriteria.And;
import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion;
import com.vaadin.event.dd.acceptcriteria.SourceIs;
import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
import com.vaadin.ui.AbstractSelect.AcceptItem;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.Tree;
import com.vaadin.ui.Tree.TargetItemAllowsChildren;
import com.vaadin.ui.Tree.TreeDragMode;
import com.vaadin.ui.Window.Notification;
public class DragDropPortlet extends HorizontalLayout{
/**
* Demonstrate moving data back and forth between a table and a tree using drag
* and drop.
*
* The tree and the table use different data structures: The category is a
* separate node in the tree and each item just has a String, whereas the table
* contains items with both a name and a category. Data conversions between
* these representations are made during drop processing.
*/
private Tree tree;
private Table table;
private Panel panel;
public static class Hardware implements Serializable {
private String name;
private String category;
public Hardware(String name, String category) {
this.name = name;
this.category = category;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setCategory(String category) {
this.category = category;
}
public String getCategory() {
return category;
}
}
public DragDropPortlet() {
setSpacing(true);
// First create the components to be able to refer to them as allowed
// drag sources
tree = new Tree("Drag from tree to table");
tree.setImmediate(true);
tree.setNullSelectionAllowed(false);
table = new Table("Drag from table to tree");
table.setWidth("100%");
panel = new Panel(); //added
panel.setHeight("15em"); //added
panel.setWidth("100%"); //added
panel.addComponent(tree); //added
// Populate the tree and set up drag & drop
initializeTree(new SourceIs(table));
// Populate the table and set up drag & drop
initializeTable(new SourceIs(tree));
// Add components
addComponent(panel); //addComponent(tree);
addComponent(table);
}
private void initializeTree(final ClientSideCriterion acceptCriterion) {
tree.setContainerDataSource(ExampleUtil.getHardwareContainer());
tree.setItemCaptionPropertyId(ExampleUtil.hw_PROPERTY_NAME);
// Expand all nodes
for (Iterator<?> it = tree.rootItemIds().iterator(); it.hasNext();) {
tree.expandItemsRecursively(it.next());
}
tree.addListener(new ItemClickEvent.ItemClickListener(){
public void itemClick(ItemClickEvent event) {
getWindow().showNotification("ItemClick is fired!!!!!");
}
});
tree.setDragMode(TreeDragMode.NODE);
tree.setDropHandler(new DropHandler() {
public void drop(DragAndDropEvent dropEvent) {
// criteria verify that this is safe
DataBoundTransferable t = (DataBoundTransferable) dropEvent
.getTransferable();
Container sourceContainer = t.getSourceContainer();
Object sourceItemId = t.getItemId();
Item sourceItem = sourceContainer.getItem(sourceItemId);
String name = sourceItem.getItemProperty("name").toString();
String category = sourceItem.getItemProperty("category")
.toString();
AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) dropEvent
.getTargetDetails());
Object targetItemId = dropData.getItemIdOver();
// find category in target: the target node itself or its parent
if (targetItemId != null && name != null && category != null) {
String treeCategory = getTreeNodeName(tree, targetItemId);
if (category.equals(treeCategory)) {
// move item from table to category'
Object newItemId = tree.addItem();
tree.getItem(newItemId)
.getItemProperty(ExampleUtil.hw_PROPERTY_NAME)
.setValue(name);
tree.setParent(newItemId, targetItemId);
tree.setChildrenAllowed(newItemId, false);
sourceContainer.removeItem(sourceItemId);
} else {
String message = name
+ " is not a "
+ treeCategory.toLowerCase().replaceAll("s$",
"");
getWindow().showNotification(message,
Notification.TYPE_WARNING_MESSAGE);
}
}
}
public AcceptCriterion getAcceptCriterion() {
// Only allow dropping of data bound transferables within
// folders.
// In this example, checking for the correct category in drop()
// rather than in the criteria.
return new And(acceptCriterion, TargetItemAllowsChildren.get(),
AcceptItem.ALL);
}
});
}
private void initializeTable(final ClientSideCriterion acceptCriterion) {
final BeanItemContainer<Hardware> tableContainer = new BeanItemContainer<Hardware>(
Hardware.class);
tableContainer.addItem(new Hardware("Dell OptiPlex 380", "Desktops"));
tableContainer.addItem(new Hardware("Benq T900HD", "Monitors"));
tableContainer.addItem(new Hardware("Lenovo ThinkPad T500", "Laptops"));
table.setContainerDataSource(tableContainer);
table.setVisibleColumns(new Object[] { "category", "name" });
// Handle drop in table: move hardware item or subtree to the table
table.setDragMode(TableDragMode.ROW);
table.setDropHandler(new DropHandler() {
public void drop(DragAndDropEvent dropEvent) {
// criteria verify that this is safe
DataBoundTransferable t = (DataBoundTransferable) dropEvent
.getTransferable();
if (!(t.getSourceContainer() instanceof Container.Hierarchical)) {
return;
}
Container.Hierarchical source = (Container.Hierarchical) t
.getSourceContainer();
Object sourceItemId = t.getItemId();
// find and convert the item(s) to move
Object parentItemId = source.getParent(sourceItemId);
// map from moved source item Id to the corresponding Hardware
LinkedHashMap<Object, Hardware> hardwareMap = new LinkedHashMap<Object, Hardware>();
if (parentItemId == null) {
// move the whole subtree
String category = getTreeNodeName(source, sourceItemId);
for (Object childId : source.getChildren(sourceItemId)) {
String name = getTreeNodeName(source, childId);
hardwareMap.put(childId, new Hardware(name, category));
}
} else {
// move a single hardware item
String category = getTreeNodeName(source, parentItemId);
String name = getTreeNodeName(source, sourceItemId);
hardwareMap.put(sourceItemId, new Hardware(name, category));
}
// move item(s) to the correct location in the table
AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) dropEvent
.getTargetDetails());
Object targetItemId = dropData.getItemIdOver();
for (Object sourceId : hardwareMap.keySet()) {
Hardware hardware = hardwareMap.get(sourceId);
if (targetItemId != null) {
switch (dropData.getDropLocation()) {
case BOTTOM:
tableContainer.addItemAfter(targetItemId, hardware);
break;
case MIDDLE:
case TOP:
Object prevItemId = tableContainer
.prevItemId(targetItemId);
tableContainer.addItemAfter(prevItemId, hardware);
break;
}
} else {
tableContainer.addItem(hardware);
}
source.removeItem(sourceId);
}
}
public AcceptCriterion getAcceptCriterion() {
return new And(acceptCriterion, AcceptItem.ALL);
}
});
}
private static String getTreeNodeName(Container.Hierarchical source,
Object sourceId) {
return (String) source.getItem(sourceId)
.getItemProperty(ExampleUtil.hw_PROPERTY_NAME).getValue();
}
}
Any help would be appreciated, thanks .8o