学习GXT有一段时间了,今天向大家介绍treeGrid.
相信大家都觉得treeGrid是很简单的吧,但是真的要和数据库整合就不是那么简单的,首先数据库必须保存一个可以形成树的机构。还有最难的就是和Gxt的Treegrid整合了,先来看看一下效果吧。
这些数据都是从数据库查询的。数据库结构如下:
cid是表主键,pid是Parent Id,也就是一个自我关联的表结构,以便于形成树结构。
POJO对象:
private int cid;
private int pid;
private List<Chapter> children;
private String lcode;
private String dorder;
private String name;
private int level;
用递归算法查询出树结构的DAO层代码:
@Override
public List<Chapter> getAllChapter() {
List<Chapter> chapters = chapterDAO.getAllChapter();
for (Chapter c : chapters) {
setChildren(c);
}
return chapters;
}
private void setChildren(Chapter c) {
List<Chapter> allChildren = chapterDAO.getAllChildren(c.getCid());
if (allChildren != null && allChildren.size() > 0) {
// 查到子节点
c.setChildren(allChildren);
for (Chapter c2 : allChildren) {
setChildren(c2);
}
}
}
添加或删除的右键效果:
更新是通过双击一行是想的,由于Treegrid的默认双击是折叠一个树节点,所以重写了onDoubleClick方法,更新的效果:
GXT客户端的类:
public class ChapterInfo extends LayoutContainer {
private ChapterManagerServiceAsync service;
private BeanModelFactory categoryFactory = BeanModelLookup.get().getFactory(Chapter.class);
private TreeGridDropTarget target;
private TreeGrid<BeanModel> treeGrid;
private TreeStore<BeanModel> store;
private TreeLoader<BeanModel> loader;
private ColumnModel cm;
private Menu contextMenu;
private RowEditor<ModelData> editor;
@Override
public void onRender(Element parent, int index) {
super.onRender(parent, index);
setWidth("100%");
setHeight("100%");
service = (ChapterManagerServiceAsync) Registry.get(Main.CHAPTER_MANAGER_SERVICE);
if (service == null) {
MessageBox box = new MessageBox();
box.setButtons(MessageBox.OK);
box.setIcon(MessageBox.INFO);
box.setTitle("Information");
box.setMessage("No service detected");
box.show();
return;
}
defineStore();
defineColumnModel();
ContentPanel cp = new ContentPanel();
cp.setBodyBorder(false);
cp.setHeading("Chapter");
cp.setButtonAlign(HorizontalAlignment.CENTER);
cp.setLayout(new FitLayout());
cp.setFrame(true);
cp.setSize("100%", "615");
treeGrid = new TreeGrid<BeanModel>(store, cm) {
@Override
protected boolean hasChildren(BeanModel parent) {
Chapter pChapter = parent.getBean();
if (pChapter.getChildren() != null && pChapter.getChildren().size() > 0) {
return true;
} else {
return false;
}
}
@Override
protected void onDoubleClick(GridEvent<BeanModel> e) {
if (e.getRowIndex() != -1) {
fireEvent(Events.RowDoubleClick, e);
if (e.getColIndex() != -1) {
fireEvent(Events.CellDoubleClick, e);
}
}
}
};
treeGrid.addListener(Events.Attach, new Listener<GridEvent<BeanModel>>() {
public void handleEvent(GridEvent<BeanModel> be) {
loader.load();
}
});
treeGrid.setBorders(true);
treeGrid.setSize(400, 400);
treeGrid.setAutoExpandColumn("name");
treeGrid.setTrackMouseOver(false);
// 行编辑器
editor = new RowEditor<ModelData>() {
@Override
public void stopEditing(boolean saveChanges) {
super.stopEditing(saveChanges);
// 如果选择的是保存按钮
if (saveChanges) {
Chapter parent = treeGrid.getTreeStore().getLastChild(
treeGrid.getSelectionModel().getSelectedItem()).getBean();
service.updateChapter(parent, new AsyncCallback<Integer>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(Integer result) {
}
});
}
}
};
editor.setClicksToEdit(ClicksToEdit.TWO);
treeGrid.addPlugin(editor);
defineContextMenu();
treeGrid.setContextMenu(contextMenu);
treeGrid.getStyle().setLeafIcon(IconHelper.createStyle("icon-page"));
new TreeGridDragSource(treeGrid);
target = new TreeGridDropTarget(treeGrid) {
@Override
protected void onDragDrop(DNDEvent event) {
super.onDragDrop(event);
int pid = activeItem.getModel().get("cid");
int level = activeItem.getModel().get("level");
List<ModelData> c = event.getData();
Chapter child = ((BeanModel) ((ModelData) c.get(0)).get("model")).getBean();
child.setPid(pid);
child.setLevel(level+1);
service.updateChapter(child, new AsyncCallback<Integer>(){
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(Integer result) {
}});
}
};
target.setAllowSelfAsSource(true);
target.setFeedback(Feedback.BOTH);
cp.add(treeGrid);
add(cp);
}
/**
* 定义右键按钮。包括添加和删除Chapter按钮
*
* @param editor
* @return contextMenu
*/
private void defineContextMenu() {
contextMenu = new Menu();
contextMenu.setWidth(140);
MenuItem insert = new MenuItem();
insert.setText("Insert Item");
insert.setIcon(Main.IMAGES.add());
insert.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
if(treeGrid.getSelectionModel().getSelectedItem()==null){
MessageBox.alert("Alter", "Please select a item!", null);
return;
}
final Chapter parent = treeGrid.getSelectionModel().getSelectedItem().getBean();
final Chapter chapter = new Chapter();
chapter.setLevel(parent.getLevel() + 1);
chapter.setLcode("EN");
chapter.setName("test");
chapter.setPid(parent.getCid());
service.insertChapter(chapter, new AsyncCallback<Chapter>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(Chapter result) {
parent.addChildren(result);
store.add(categoryFactory.createModel(parent), categoryFactory.createModel(result), true);
treeGrid.setExpanded(categoryFactory.createModel(parent), true);
int j = treeGrid.getStore().indexOf(categoryFactory.createModel(result));
editor.startEditing(j, true);
}
});
}
});
MenuItem remove = new MenuItem();
remove.setText("Remove Selected");
remove.setIcon(Main.IMAGES.delete());
remove.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
final Chapter item = treeGrid.getSelectionModel().getSelectedItem().getBean();
BeanModel parent = treeGrid.getTreeStore().getParent(treeGrid.getSelectionModel().getSelectedItem());
//删除一个parent的Children
if( parent!=null){
((Chapter) treeGrid.getTreeStore().getParent(treeGrid.getSelectionModel().getSelectedItem()).getBean())
.getChildren().remove(item);
}else{
treeGrid.getTreeStore().remove(treeGrid.getSelectionModel().getSelectedItem());
}
if (item.getChildren() != null && item.getChildren().size() > 0) {
MessageBox.alert("DeleteChapter", "Please first delete the subnodes", null);
} else {
store.remove(treeGrid.getTreeStore().getParent(treeGrid.getSelectionModel().getSelectedItem()),
treeGrid.getSelectionModel().getSelectedItem());
service.deleteChapter(item.getCid(), new AsyncCallback<Integer>() {
@Override
public void onFailure(Throwable caught) {
MessageBox.alert("DeleteChapter", "Failure", null);
}
@Override
public void onSuccess(Integer result) {
MessageBox.alert("DeleteChapter", "Success", null);
}
});
}
}
});
contextMenu.add(insert);
contextMenu.add(remove);
}
/**
* 定义列模型和相应编辑器.
*/
private void defineColumnModel() {
ColumnConfig name = new ColumnConfig("name", "Name", 100);
TextField<String> nameTest = new TextField<String>();
nameTest.setAllowBlank(false);
name.setEditor(new CellEditor(nameTest));
ColumnConfig cid = new ColumnConfig("cid", "Cid", 100);
ColumnConfig lcode = new ColumnConfig("lcode", "Lcode", 100);
final SimpleComboBox<String> combo = new SimpleComboBox<String>();
combo.setName("lang");
combo.setAllowBlank(false);
combo.setEditable(false);
combo.setForceSelection(true);
combo.setFieldLabel("Lang");
combo.setForceSelection(true);
combo.setTriggerAction(TriggerAction.ALL);
combo.add("KR");
combo.add("CH");
combo.add("EN");
combo.add("JP");
CellEditor lcodeEditor = new CellEditor(combo) {
@Override
public Object preProcessValue(Object value) {
if (value == null) {
return value;
}
return combo.findModel(value.toString());
}
@Override
public Object postProcessValue(Object value) {
if (value == null) {
return value;
}
return ((ModelData) value).get("value");
}
};
lcode.setEditor(lcodeEditor);
ColumnConfig level = new ColumnConfig("level", "Level", 100);
ColumnConfig dorder = new ColumnConfig("dorder", "Dorder", 100);
dorder.setEditor(new CellEditor(new TextField<String>()));
name.setRenderer(new TreeGridCellRenderer<ModelData>());
cm = new ColumnModel(Arrays.asList(name, cid, lcode, level, dorder));
}
/**
* 定义数据源
*/
private void defineStore() {
RpcProxy<List<BeanModel>> proxy = new RpcProxy<List<BeanModel>>() {
@Override
protected void load(Object loadConfig, final AsyncCallback<List<BeanModel>> callback) {
if (loadConfig == null) {
service.getAllChapter(new AsyncCallback<List<Chapter>>() {
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
public void onSuccess(List<Chapter> result) {
callback.onSuccess(categoryFactory.createModel(result));
}
});
} else {
BeanModel model = (BeanModel) loadConfig;
callback.onSuccess(categoryFactory.createModel(((Chapter) model.getBean()).getChildren()));
}
}
};
// tree loader
loader = new BaseTreeLoader<BeanModel>(proxy) {
@Override
public boolean hasChildren(BeanModel parent) {
if (((Chapter) parent.getBean()).getChildren() != null) {
return ((Chapter) parent.getBean()).getChildren().size() > 0;
} else {
return false;
}
}
};
store = new TreeStore<BeanModel>(loader);
}
由于部分代码关系到公司安全,不便于贴出来,希望大家谅解,任何问题可以留言,谢谢。