学习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);
}
由于部分代码关系到公司安全,不便于贴出来,希望大家谅解,任何问题可以留言,谢谢。
- 大小: 11 KB
- 大小: 2 KB
- 大小: 6 KB
- 大小: 5.1 KB
分享到:
相关推荐
在本文中,我们将深入探讨GXT组件的使用,特别是关于Aggregation Grid的教程。GXT是Sencha提供的一款强大的JavaScript库,专为构建企业级Web应用程序而设计,它提供了丰富的UI组件和数据网格功能。Aggregation Grid...
GXT 下拉树(Combo Tree)基本实现GXT 下拉树(Combo Tree)基本实现GXT 下拉树(Combo Tree)基本实现GXT 下拉树(Combo Tree)基本实现GXT 下拉树(Combo Tree)基本实现GXT 下拉树(Combo Tree)基本实现GXT 下拉树(Combo ...
`Grid`可以绑定到各种数据源,如ListModel或Store,支持分页、排序、过滤等功能。在Auto Height Grid中,我们关注的是如何让`Grid`组件能够自适应其内容的高度。 实现Auto Height Grid的关键在于配置`Grid`的布局和...
该文档深入讲解了GXT中的各种组件,如Grid、Window、Panel等的使用方法,同时可能包括了数据绑定、事件处理、组件样式定制等内容,旨在提升开发者对GXT组件的实际操作能力。 3. **JavaBeanSupportwithExtGWT.docx*...
2. **数据网格(Data Grid)**:GXT的数据网格组件能够轻松处理大量数据,支持动态加载、分页、排序和过滤功能。这对于展示和操作复杂数据集的应用场景非常有用。 3. **图表(Charts)**:GXT的图表组件提供了多种...
1. **组件库**:GXT提供了大量的UI组件,如表格(Grid)、树形视图(Tree)、菜单(Menu)、对话框(Dialog)等,这些组件在设计上遵循了MVC模式,易于定制和扩展。 2. **数据绑定**:GXT支持双向数据绑定,使得...
3. 使用GXT的数据绑定机制,将数据模型与UI组件关联,这样当数据改变时,UI会自动更新,反之亦然。 4. 考虑性能优化,如延迟加载,只在需要时加载下级数据,以减少初始加载时间和网络传输量。 通过分析和理解这些...
- **数据绑定**:GXT支持双向数据绑定,可以轻松地将界面组件与后台数据模型关联,简化了数据管理。 - **响应式设计**:提供多种屏幕尺寸和设备的支持,适应不同平台和设备的用户体验。 - **主题定制**:提供多种...
- **数据表格**:详细介绍如何使用Grid组件展示和操作数据。 - **远程数据服务**:实现客户端与服务器之间的数据交互。 4. **高级特性** - **自定义组件**:教授如何根据需求定制特定的UI组件。 - **图表与可视...
GXT提供了大量的组件,如表格(Grid)、树(Tree)、表单(Form)、菜单(Menu)等。API文档详细介绍了这些组件的创建、配置和使用方法,包括它们的属性、事件和方法。开发者可以通过查阅文档来了解如何实现特定...
GXT提供了丰富的组件、数据绑定、布局管理以及主题定制等功能,让开发者能够利用Java语言开发出具有桌面应用级别的用户体验的Web应用。 "包含resource"这部分意味着压缩包中可能包含了GXT库的资源文件,这些文件...
2. **数据绑定**:GXT支持数据模型与视图的自动绑定,简化了数据管理。开发者可以通过简单的API操作数据模型,视图会自动更新,反之亦然。 3. **主题系统**:GXT允许开发者定义和应用不同的皮肤主题,以改变应用的...
在GXT 2.2.5中,数据绑定和分页功能得到了进一步优化。通过ModelData和Store对象,可以轻松实现数据的双向绑定,使得界面组件和后台数据之间的交互更为便捷。同时,数据网格支持动态加载和分页,提升了用户体验。 ...
GXT是Ext JS的一个Java版本,提供了大量的桌面级UI组件,如表格、图表、树形视图等,同时还支持数据绑定和分页功能。GXT的优势在于其丰富的界面组件和对响应式设计的支持,使得开发者能够构建出类似桌面应用的用户...
随着对GXT库的深入理解和实践,你可以构建更复杂的用户界面,利用其强大的组件和数据绑定功能,实现高效、美观的Web应用。在实际开发中,还需要学习GXT提供的各种组件、布局、事件处理、数据模型以及远程服务调用等...
3. **数据绑定**:GXT提供了数据模型和视图之间的绑定机制,简化了数据管理。 4. **主题定制**:可以自定义皮肤和主题,满足不同项目的视觉需求。 5. **增强的性能**:GXT对GWT进行了优化,提高了组件渲染速度和整体...
从给定的内容来看,这篇“gxt初学进阶教程”主要介绍了一个基于GWT(Google Web Toolkit)的扩展工具库ExtGWT,也被称作GXT,用于帮助Java程序员在Web开发中创建富客户端应用程序。以下是根据提供的文件内容总结出的...
在列模型中,你可以使用`ColumnConfig`对象来指定列的属性,包括列宽、标题和数据绑定等。为了创建分组,你需要在`ColumnConfig`中设置`grouped`属性为`true`,并提供分组的标题。 例如: ```java ColumnConfig ...
GXT等第三方库的出现,正是为了弥补这一空缺,提供更加丰富的UI组件和高级功能,如数据绑定、图表绘制等,极大地提升了开发效率和用户体验。 #### 实践操作:从GWT到GXT - **下载并集成GXT SDK**:从Sencha官网...
2. 数据绑定和模型层支持,方便地处理数据与视图的同步。 3. 强大的表格组件,支持排序、分页、过滤和复杂的列格式化。 4. 图表组件,用于创建动态和交互式的统计图表,如柱状图、饼图、线图等。 5. 丰富的布局管理...