|
Processing... Drag a contact from one group to another, double click contact to open a chat window.
Description & Source Code
In this demo, the items are made drag and drop-able using
Following is a snap of public class AdvancedTreeModel extends SimpleTreeModel { public void remove(SimpleTreeNode parent, int indexFrom, int indexTo) {...} public void remove(SimpleTreeNode target) {...} public void insert(Object parent, int indexFrom, int indexTo, SimpleTreeNode[] newNodes) {...} public void add(SimpleTreeNode parent, Object[] newNodes) {...} } dynamic_tree.zul
<window id="demoWindow" apply="demo.tree.dynamic_tree.DemoComposer">
<style>
.h-inline-block {
display: inline-block;
_display: inline;
}
</style>
<tree id="tree" width="300px" >
<treecols>
<treecol label="My Contact List" />
</treecols>
</tree>
</window>
dialog.zul
<zk>
<style><![CDATA[
.dialog .msg .z-label {
font-weight: bold;
font-style: italic;
color: #008BB6;
}
.dialog .z-borderlayout,
.dialog .z-north, .dialog .z-south,
.dialog .z-east, .dialog .z-west,
.dialog .z-center, .dialog .z-panel-children ,
.dialog.z-panel-noheader div.z-toolbar {
border: 0 none;
background:transparent;
}
.dialog .viewer .z-label {
font-weight: bold;
}
.dialog .viewer pre, .dialog .viewer .content {
font-weight: normal;
padding-left:20px;
margin: 0;
}
.z-south-splitter {
border: 0 none;
}
]]></style>
<panel id="panel" width="500px" height="400px" border="normal" sclass="dialog">
<toolbar sclass="msg">This is a sample IM dialog. Nothing will be send back.</toolbar>
<panelchildren>
<borderlayout>
<west size="130px">
<borderlayout height="370px" width="100%">
<north>
<image src="/widgets/tree/dynamic_tree/img/contact.gif" width="121px" height="118px"/>
</north>
<south>
<image src="/widgets/tree/dynamic_tree/img/contact_zk.gif" width="121px" height="118px"/>
</south>
</borderlayout>
</west>
<east width="360px" border="0" vflex="1">
<borderlayout height="370px">
<center vflex="1">
<vlayout id="viewer" sclass="viewer" style="overflow:auto;">
Ryan@zkoss.org says:
<label sclass="content">There ?</label>
${arg.name} - (A ZK Lover) says:
<label sclass="content">Yeap</label>
</vlayout>
</center>
<south splittable="true" height="130px" >
<div>
<textbox id="text" multiline="true" width="100%" height="80px" style="margin: 0 0 0 1px"
value="This Demo is so cool" />
<toolbar mold="panel" align="center">
<button label="Send" width="65px">
<attribute name="onClick"><![CDATA[
if (text.value.isEmpty())
return;
Div div = new Div();
new Label("Ryan@zkoss.org says:").setParent(div);
Html content = new Html("<pre>" + text.value + "</pre>");
viewer.appendChild(div);
viewer.appendChild(content);
text.value = "";
]]></attribute>
</button>
<button label="Clear" width="65px" onClick='text.value = ""' />
</toolbar>
</div>
</south>
</borderlayout>
</east>
</borderlayout>
</panelchildren>
</panel>
</zk>
DemoComposer.java
package demo.tree.dynamic_tree;
import java.util.HashMap;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.DropEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.Image;
import org.zkoss.zul.Label;
import org.zkoss.zul.Tree;
import org.zkoss.zul.Treecell;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;
import org.zkoss.zul.Window;
import demo.data.ContactList;
import demo.data.pojo.Contact;
public class DemoComposer extends SelectorComposer<Component> {
private static final long serialVersionUID = 3814570327995355261L;
@Wire
private Window demoWindow;
@Wire
private Tree tree;
private AdvancedTreeModel contactTreeModel;
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
contactTreeModel = new AdvancedTreeModel(new ContactList().getRoot());
tree.setItemRenderer(new ContactTreeRenderer());
tree.setModel(contactTreeModel);
}
/**
* The structure of tree
*
* <pre>
* <treeitem>
* <treerow>
* <treecell>...</treecell>
* </treerow>
* <treechildren>
* <treeitem>...</treeitem>
* </treechildren>
* </treeitem>
* </pre>
*/
private final class ContactTreeRenderer implements TreeitemRenderer<ContactTreeNode> {
@Override
public void render(final Treeitem treeItem, ContactTreeNode treeNode, int index) throws Exception {
ContactTreeNode ctn = treeNode;
Contact contact = (Contact) ctn.getData();
Treerow dataRow = new Treerow();
dataRow.setParent(treeItem);
treeItem.setValue(ctn);
treeItem.setOpen(ctn.isOpen());
if (!isCategory(contact)) { // Contact Row
Hlayout hl = new Hlayout();
hl.appendChild(new Image("/widgets/tree/dynamic_tree/img/" + contact.getProfilepic()));
hl.appendChild(new Label(contact.getName()));
hl.setSclass("h-inline-block");
Treecell treeCell = new Treecell();
treeCell.appendChild(hl);
dataRow.setDraggable("true");
dataRow.appendChild(treeCell);
dataRow.addEventListener(Events.ON_DOUBLE_CLICK, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
ContactTreeNode clickedNodeValue = (ContactTreeNode) ((Treeitem) event.getTarget().getParent())
.getValue();
Window w = new Window("ZK IM - " + ((Contact) clickedNodeValue.getData()).getName(), "normal",
true);
w.setPosition("parent");
w.setParent(demoWindow);
HashMap<String, String> dataArgs = new HashMap<String, String>();
dataArgs.put("name", clickedNodeValue.getData().getName());
Executions.createComponents("/widgets/tree/dynamic_tree/dialog.zul", w, dataArgs);
w.doOverlapped();
}
});
} else { // Category Row
dataRow.appendChild(new Treecell(contact.getCategory()));
}
// Both category row and contact row can be item dropped
dataRow.setDroppable("true");
dataRow.addEventListener(Events.ON_DROP, new EventListener<Event>() {
@SuppressWarnings("unchecked")
@Override
public void onEvent(Event event) throws Exception {
// The dragged target is a TreeRow belongs to an
// Treechildren of TreeItem.
Treeitem draggedItem = (Treeitem) ((DropEvent) event).getDragged().getParent();
ContactTreeNode draggedValue = (ContactTreeNode) draggedItem.getValue();
Treeitem parentItem = treeItem.getParentItem();
contactTreeModel.remove(draggedValue);
if (isCategory((Contact) ((ContactTreeNode) treeItem.getValue()).getData())) {
contactTreeModel.add((ContactTreeNode) treeItem.getValue(),
new DefaultTreeNode[] { draggedValue });
} else {
int index = parentItem.getTreechildren().getChildren().indexOf(treeItem);
if(parentItem.getValue() instanceof ContactTreeNode) {
contactTreeModel.insert((ContactTreeNode)parentItem.getValue(), index, index,
new DefaultTreeNode[] { draggedValue });
}
}
}
});
}
private boolean isCategory(Contact contact) {
return contact.getName() == null;
}
}
}AdvancedTreeModel.java
package demo.tree.dynamic_tree;
import org.zkoss.zul.DefaultTreeModel;
import org.zkoss.zul.DefaultTreeNode;
import demo.data.pojo.Contact;
public class AdvancedTreeModel extends DefaultTreeModel<Contact> {
private static final long serialVersionUID = -5513180500300189445L;
DefaultTreeNode<Contact> _root;
public AdvancedTreeModel(ContactTreeNode contactTreeNode) {
super(contactTreeNode);
_root = contactTreeNode;
}
/**
* remove the nodes which parent is <code>parent</code> with indexes
* <code>indexes</code>
*
* @param parent
* The parent of nodes are removed
* @param indexFrom
* the lower index of the change range
* @param indexTo
* the upper index of the change range
* @throws IndexOutOfBoundsException
* - indexFrom < 0 or indexTo > number of parent's children
*/
public void remove(DefaultTreeNode<Contact> parent, int indexFrom, int indexTo) throws IndexOutOfBoundsException {
DefaultTreeNode<Contact> stn = parent;
for (int i = indexTo; i >= indexFrom; i--)
try {
stn.getChildren().remove(i);
} catch (Exception exp) {
exp.printStackTrace();
}
}
public void remove(DefaultTreeNode<Contact> target) throws IndexOutOfBoundsException {
int index = 0;
DefaultTreeNode<Contact> parent = null;
// find the parent and index of target
parent = dfSearchParent(_root, target);
for (index = 0; index < parent.getChildCount(); index++) {
if (parent.getChildAt(index).equals(target)) {
break;
}
}
remove(parent, index, index);
}
/**
* insert new nodes which parent is <code>parent</code> with indexes
* <code>indexes</code> by new nodes <code>newNodes</code>
*
* @param parent
* The parent of nodes are inserted
* @param indexFrom
* the lower index of the change range
* @param indexTo
* the upper index of the change range
* @param newNodes
* New nodes which are inserted
* @throws IndexOutOfBoundsException
* - indexFrom < 0 or indexTo > number of parent's children
*/
public void insert(DefaultTreeNode<Contact> parent, int indexFrom, int indexTo, DefaultTreeNode<Contact>[] newNodes)
throws IndexOutOfBoundsException {
DefaultTreeNode<Contact> stn = parent;
for (int i = indexFrom; i <= indexTo; i++) {
try {
stn.getChildren().add(i, newNodes[i - indexFrom]);
} catch (Exception exp) {
throw new IndexOutOfBoundsException("Out of bound: " + i + " while size=" + stn.getChildren().size());
}
}
}
/**
* append new nodes which parent is <code>parent</code> by new nodes
* <code>newNodes</code>
*
* @param parent
* The parent of nodes are appended
* @param newNodes
* New nodes which are appended
*/
public void add(DefaultTreeNode<Contact> parent, DefaultTreeNode<Contact>[] newNodes) {
DefaultTreeNode<Contact> stn = (DefaultTreeNode<Contact>) parent;
for (int i = 0; i < newNodes.length; i++)
stn.getChildren().add(newNodes[i]);
}
private DefaultTreeNode<Contact> dfSearchParent(DefaultTreeNode<Contact> node, DefaultTreeNode<Contact> target) {
if (node.getChildren() != null && node.getChildren().contains(target)) {
return node;
} else {
int size = getChildCount(node);
for (int i = 0; i < size; i++) {
DefaultTreeNode<Contact> parent = dfSearchParent((DefaultTreeNode<Contact>) getChild(node, i), target);
if (parent != null) {
return parent;
}
}
}
return null;
}
}
ContactTreeNode.java
package demo.tree.dynamic_tree;
import org.zkoss.zul.DefaultTreeNode;
import demo.data.pojo.Contact;
public class ContactTreeNode extends DefaultTreeNode<Contact> {
private static final long serialVersionUID = -7012663776755277499L;
private boolean open = false;
public ContactTreeNode(Contact data, DefaultTreeNode<Contact>[] children) {
super(data, children);
}
public ContactTreeNode(Contact data, DefaultTreeNode<Contact>[] children, boolean open) {
super(data, children);
setOpen(open);
}
public ContactTreeNode(Contact data) {
super(data);
}
public boolean isOpen() {
return open;
}
public void setOpen(boolean open) {
this.open = open;
}
}
ContactList.java
package demo.data;
import demo.data.pojo.Contact;
import demo.tree.dynamic_tree.ContactTreeNode;
public class ContactList {
public final static String Category = "Category";
public final static String Contact = "Contact";
private ContactTreeNode root;
public ContactList() {
root = new ContactTreeNode(null,
new ContactTreeNode[] {
new ContactTreeNode(new Contact("Friend"),new ContactTreeNode[] {
new ContactTreeNode(new Contact("High School"), new ContactTreeNode[] {
new ContactTreeNode(new Contact("Fernando Terrell", "Contact.png")),
new ContactTreeNode(new Contact("Stanley Larson", "Contact.png"))
},true),
new ContactTreeNode(new Contact("University"), new ContactTreeNode[] {
new ContactTreeNode(new Contact("Camryn Breanna", "Contact.png")),
new ContactTreeNode(new Contact("Juliana Isabela","Contact-gu.png")),
new ContactTreeNode(new Contact("Holden Craig", "Contact-g.png"))
}),
new ContactTreeNode(new Contact("Emma Jones", "Contact-i.png")),
new ContactTreeNode(new Contact("Eric Franklin", "Contact.png")),
new ContactTreeNode(new Contact("Alfred Wong", "Contact.png")),
new ContactTreeNode(new Contact("Miguel Soto", "Contact.png"))
},true),
new ContactTreeNode(new Contact("Work"),new ContactTreeNode[] {
new ContactTreeNode(new Contact("Andrew Willis", "Contact.png")),
new ContactTreeNode(new Contact("Russell Thomas", "Contact-jq.png")),
new ContactTreeNode(new Contact("Donovan Marcus", "Contact.png"))
})
},true
);
}
public ContactTreeNode getRoot() {
return root;
}
}
Contact.java
package demo.data.pojo;
public class Contact {
private final String name;
private final String category;
public Contact(String category) {
this.category = category;
this.name = null;
this.profilepic = null;
}
public Contact(String name, String profilepic) {
this.name = name;
this.profilepic = profilepic;
this.category = null;
}
public String getName() {
return name;
}
public String getCategory() {
return category;
}
public String getProfilepic() {
return profilepic;
}
private final String profilepic;
}
Copyright © 2005-2025 Potix Corporation All rights reserved.
|
|
Processing... |