我有一个带有创作者(作者)层次结构的有声读物数据库。我使用父ID作为关系。如果我的作者的名字拼写不同,我会将其作为拼写正确的作者的孩子。我使用JPA创建和访问数据库。 我在Tree UI中加载JPAContainer并且可以正常工作。 但是当我将一个Item拖放到另一个Item上时,拖动的Item将成为新创建的父项的子项,其中包含放置目标的名称。它不应该创建新的父级,而只需将子级添加到droptarget。 我在这里错过了什么?
Creator.java
@Entity
@Table(name = "creator")
@NamedQueries({
@NamedQuery(name = "Creator.findAll", query = "SELECT c FROM Creator c"),
@NamedQuery(name = "Creator.findByName", query = "SELECT c FROM Creator c WHERE c.name = :name") })
public class Creator implements Serializable {
private static final long serialVersionUID = 1L;
@TableGenerator(name = "Creator_Gen", table = "ID_GEN", pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", pkColumnValue = "Creator_Gen", initialValue = 1)
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "Creator_Gen")
@Column(unique = true, nullable = false)
private Integer id;
@Column(length = 10000)
private String bio;
@Temporal(TemporalType.DATE)
private Date birthdate;
@Column(nullable = false, length = 50)
private String name;
// bi-directional many-to-one association to Book
@OneToMany(mappedBy = "creator")
private List<Book> books;
// bi-directional many-to-one association to Nationality
@ManyToOne(cascade = { CascadeType.PERSIST })
@JoinColumn(name = "nationality")
private Nationality nationality;
@Transient
private Boolean superCreator;
@ManyToOne(targetEntity=model.Creator.class)
@OrderBy("name")
@JoinColumn(name="parent",referencedColumnName="id")
private Creator parent;
@OneToMany(mappedBy="parent")
@OrderBy("name")
private List<Creator> children;
public Creator() {
}
public Creator(String author) {
this.name = author;
}
public Integer getId() {
return this.id;
}
Vaadin UI树代码BooksMain.java的一部分。
public BooksMainView() {
JPAContainer<Creator> creators = new JPAContainer<Creator>(
Creator.class) {
private static final long serialVersionUID = 1L;
@Override
public boolean areChildrenAllowed(Object itemId) {
return getItem(itemId).getEntity().getChildren().size() > 0;
}
};
EntityManager em = JPAContainerFactory
.createEntityManagerForPersistenceUnit(BookPersistenceManager.PERSISTENCE_UNIT);
creators.setEntityProvider(new CachingLocalEntityProvider<Creator>(
Creator.class, em));
creators.setParentProperty("parent");
buildTree();
}
private void buildTree() {
groupTree = new Tree("creators", creators);
groupTree.setItemCaptionMode(ItemCaptionMode.PROPERTY);
groupTree.setItemCaptionPropertyId("id");
groupTree.setImmediate(true);
groupTree.setSelectable(true);
groupTree.setDragMode(TreeDragMode.NODE);
// Allow the tree to receive drag drops and handle them
groupTree.setDropHandler(new DropHandler() {
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
public void drop(DragAndDropEvent event) {
// Wrapper for the object that is dragged
Transferable t = event.getTransferable();
// Make sure the drag source is the same tree
if (t.getSourceComponent() != groupTree)
return;
AbstractSelectTargetDetails target = (AbstractSelectTargetDetails) event
.getTargetDetails();
// Get ids of the dragged item and the target item
Object sourceItemId = t.getData("itemId");
Object targetItemId = target.getItemIdOver();
// On which side of the target the item was dropped
VerticalDropLocation location = target.getDropLocation();
HierarchicalEntityContainer<Creator> container = (HierarchicalEntityContainer<Creator>) groupTree
.getContainerDataSource();
EntityItem<Creator> src = container.getItem(sourceItemId);
EntityItem<Creator> dst = container.getItem(targetItemId);
// Drop right on an item -> make it a child
if (location == VerticalDropLocation.MIDDLE) {
System.out.println("source:" + src.getItemProperty("name")
+ " id:" + src.getItemProperty("id"));
System.out.println("target:" + dst.getItemProperty("name")
+ " id:" + dst.getItemProperty("id"));
src.getItemProperty("parent").setValue(dst);
}
}
});
setFirstComponent(groupTree);
}
答案 0 :(得分:0)
已经过了一段时间,但解决了这个问题。解决方案与DropHandler中的预期一致。您需要将属性&#34; parent&#34;设置为目标实体。
if (location == VerticalDropLocation.MIDDLE) {
if (src.getItemId() != dst.getItemId()) {
src.getItemProperty("parent").setValue(dst.getEntity());
creators.refresh();
}
} else {
src.getItemProperty("parent").setValue(null);
creators.refresh();
}
这里是完整的类源代码。
public class CreatorTree extends Tree {
private static final long serialVersionUID = 9071565734995148942L;
private HierarchicalCreatorContainer creators;
private Creator creatorFilter;
private SearchFilter filter;
private ArrayList<CreatorSelectionListener> mSelectionListeners;
public CreatorTree(HierarchicalCreatorContainer creators) {
super("creators", creators);
this.creators = creators;
buildTree();
this.mSelectionListeners = new ArrayList<CreatorSelectionListener>();
}
public CreatorTree(HierarchicalCreatorContainer creators,
SearchFilter filter) {
this(creators);
this.filter = filter;
filter.addCreatorContainer(creators);
}
private void buildTree() {
setItemCaptionMode(ItemCaptionMode.PROPERTY);
setItemCaptionPropertyId("name");
// expand tree
// for (Object rootId : creators.rootItemIds())
// groupTree.expandItemsRecursively(rootId);
setImmediate(true);
setSelectable(true);
setDragMode(TreeDragMode.NODE);
addValueChangeListener(new Property.ValueChangeListener() {
private static final long serialVersionUID = 1L;
private Object prev_sel_id;
@Override
public void valueChange(
com.vaadin.data.Property.ValueChangeEvent event) {
Object id = event.getProperty().getValue();
if (id != null) {
Creator entity = creators.getItem(id).getEntity();
if (entity.hasChildren()) {
expandItem(id);
if (prev_sel_id != null && prev_sel_id != id)
collapseItem(prev_sel_id);
prev_sel_id = id;
}
creatorFilter = entity;
for (CreatorSelectionListener sl : mSelectionListeners) {
sl.creatorSelected(entity);
}
} else if (creatorFilter != null) {
creatorFilter = null;
}
filter.updateFilters(creatorFilter);
}
});
// Allow the tree to receive drag drops and handle them
setDropHandler(new DropHandler() {
private static final long serialVersionUID = -3077253259924255881L;
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
public void drop(DragAndDropEvent event) {
// Wrapper for the object that is dragged
Transferable t = event.getTransferable();
AbstractSelectTargetDetails target = (AbstractSelectTargetDetails) event
.getTargetDetails();
// Get ids of the dragged item and the target item
Object sourceItemId = t.getData("itemId");
Object targetItemId = target.getItemIdOver();
// On which side of the target the item was dropped
VerticalDropLocation location = target.getDropLocation();
HierarchicalEntityContainer<Creator> container = (HierarchicalEntityContainer<Creator>) getContainerDataSource();
EntityItem<Creator> src = container.getItem(sourceItemId);
EntityItem<Creator> dst = container.getItem(targetItemId);
System.out.println("source:" + src.getItemProperty("name")
+ " id:" + src.getItemProperty("id"));
System.out.println("target:" + dst.getItemProperty("name")
+ " id:" + dst.getItemProperty("id"));
// Drop right on an item -> make it a child
if (location == VerticalDropLocation.MIDDLE) {
if (src.getItemId() != dst.getItemId()) {
src.getItemProperty("parent").setValue(dst.getEntity());
creators.refresh();
}
} else {
src.getItemProperty("parent").setValue(null);
creators.refresh();
}
}
});
}
public void refresh() {
this.getUI().getSession().lock();
try {
creators.refresh();
} finally {
this.getUI().getSession().unlock();
}
}
public void addSelectionListener(CreatorSelectionListener selectionlistener) {
mSelectionListeners.add(selectionlistener);
}
}