`
java_doc
  • 浏览: 19816 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

gxt tree grid 绑定数据库

    博客分类:
  • GXT
阅读更多

学习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
分享到:
评论
3 楼 rgbwoo 2010-07-06  
照着您的代码,做了一个,但是只能显示第一层,不显示子节点?为什么呢?
2 楼 java_doc 2009-11-27  
第一个问题:由于代码不全,我不能确定具体的错误原因。
第二个问题:你向GWT客户端返回一个ResultSet类型是肯定不行的,建议你用List对象替换ResultSet就可以了。
1 楼 seekyourcolor 2009-11-26  
大哥,我刚学GXT,遇到一些麻烦请帮助。
我在做一个从oracle数据库取数据的树,我用的是oracle thin硬链接(方便测试),遇到2个问题:
1)"[ERROR] Line 13: The method forName(String) is undefined for the type Class" 这个貌似说oracle驱动有问题,Class.forName()...但是这个链接我测试能通过的,不知道为什么在GXT里面报错
2)"[ERROR] Line 28: No source code is available for type java.sql.Connection; did you forget to inherit a required module?"
   "[ERROR] Line 29: No source code is available for type java.sql.Statement; did you forget to inherit a required module?" 为什么这些Connection Statement ResultSet都找不到文件,要在哪里注册吗 怎么注册啊?


谢谢啊~~~~

相关推荐

    GXT组件使用教程4——Aggregation Grid

    在本文中,我们将深入探讨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 Tree)基本实现GXT 下拉树(Combo ...

    GXT组件使用教程2——Auto Height Grid

    `Grid`可以绑定到各种数据源,如ListModel或Store,支持分页、排序、过滤等功能。在Auto Height Grid中,我们关注的是如何让`Grid`组件能够自适应其内容的高度。 实现Auto Height Grid的关键在于配置`Grid`的布局和...

    GXT组件使用教程

    该文档深入讲解了GXT中的各种组件,如Grid、Window、Panel等的使用方法,同时可能包括了数据绑定、事件处理、组件样式定制等内容,旨在提升开发者对GXT组件的实际操作能力。 3. **JavaBeanSupportwithExtGWT.docx*...

    Gxt_BLOG(GXt项目)

    2. **数据网格(Data Grid)**:GXT的数据网格组件能够轻松处理大量数据,支持动态加载、分页、排序和过滤功能。这对于展示和操作复杂数据集的应用场景非常有用。 3. **图表(Charts)**:GXT的图表组件提供了多种...

    gxt-api-2.2.5 doc

    1. **组件库**:GXT提供了大量的UI组件,如表格(Grid)、树形视图(Tree)、菜单(Menu)、对话框(Dialog)等,这些组件在设计上遵循了MVC模式,易于定制和扩展。 2. **数据绑定**:GXT支持双向数据绑定,使得...

    GXT Cascade ComboBox Samples

    3. 使用GXT的数据绑定机制,将数据模型与UI组件关联,这样当数据改变时,UI会自动更新,反之亦然。 4. 考虑性能优化,如延迟加载,只在需要时加载下级数据,以减少初始加载时间和网络传输量。 通过分析和理解这些...

    GXT 软件包和API

    - **数据绑定**:GXT支持双向数据绑定,可以轻松地将界面组件与后台数据模型关联,简化了数据管理。 - **响应式设计**:提供多种屏幕尺寸和设备的支持,适应不同平台和设备的用户体验。 - **主题定制**:提供多种...

    GXT 学习的好书

    - **数据表格**:详细介绍如何使用Grid组件展示和操作数据。 - **远程数据服务**:实现客户端与服务器之间的数据交互。 4. **高级特性** - **自定义组件**:教授如何根据需求定制特定的UI组件。 - **图表与可视...

    GXT v2.2.1 API doc

    GXT提供了大量的组件,如表格(Grid)、树(Tree)、表单(Form)、菜单(Menu)等。API文档详细介绍了这些组件的创建、配置和使用方法,包括它们的属性、事件和方法。开发者可以通过查阅文档来了解如何实现特定...

    Gxt,包含resource

    GXT提供了丰富的组件、数据绑定、布局管理以及主题定制等功能,让开发者能够利用Java语言开发出具有桌面应用级别的用户体验的Web应用。 "包含resource"这部分意味着压缩包中可能包含了GXT库的资源文件,这些文件...

    gxt-1.2.3.jar.zip

    2. **数据绑定**:GXT支持数据模型与视图的自动绑定,简化了数据管理。开发者可以通过简单的API操作数据模型,视图会自动更新,反之亦然。 3. **主题系统**:GXT允许开发者定义和应用不同的皮肤主题,以改变应用的...

    gxt-2.2.5.zip

    在GXT 2.2.5中,数据绑定和分页功能得到了进一步优化。通过ModelData和Store对象,可以轻松实现数据的双向绑定,使得界面组件和后台数据之间的交互更为便捷。同时,数据网格支持动态加载和分页,提升了用户体验。 ...

    gxt、gwt与spring结合使用

    GXT是Ext JS的一个Java版本,提供了大量的桌面级UI组件,如表格、图表、树形视图等,同时还支持数据绑定和分页功能。GXT的优势在于其丰富的界面组件和对响应式设计的支持,使得开发者能够构建出类似桌面应用的用户...

    一步一步教你新建GXT项目

    随着对GXT库的深入理解和实践,你可以构建更复杂的用户界面,利用其强大的组件和数据绑定功能,实现高效、美观的Web应用。在实际开发中,还需要学习GXT提供的各种组件、布局、事件处理、数据模型以及远程服务调用等...

    gwt + gxt jar包

    3. **数据绑定**:GXT提供了数据模型和视图之间的绑定机制,简化了数据管理。 4. **主题定制**:可以自定义皮肤和主题,满足不同项目的视觉需求。 5. **增强的性能**:GXT对GWT进行了优化,提高了组件渲染速度和整体...

    gxt初学进阶教程

    从给定的内容来看,这篇“gxt初学进阶教程”主要介绍了一个基于GWT(Google Web Toolkit)的扩展工具库ExtGWT,也被称作GXT,用于帮助Java程序员在Web开发中创建富客户端应用程序。以下是根据提供的文件内容总结出的...

    GXT组件使用教程3——Column Group

    在列模型中,你可以使用`ColumnConfig`对象来指定列的属性,包括列宽、标题和数据绑定等。为了创建分组,你需要在`ColumnConfig`中设置`grouped`属性为`true`,并提供分组的标题。 例如: ```java ColumnConfig ...

    ext gwt gxt初学教程

    GXT等第三方库的出现,正是为了弥补这一空缺,提供更加丰富的UI组件和高级功能,如数据绑定、图表绘制等,极大地提升了开发效率和用户体验。 #### 实践操作:从GWT到GXT - **下载并集成GXT SDK**:从Sencha官网...

    GXT的JAR包

    2. 数据绑定和模型层支持,方便地处理数据与视图的同步。 3. 强大的表格组件,支持排序、分页、过滤和复杂的列格式化。 4. 图表组件,用于创建动态和交互式的统计图表,如柱状图、饼图、线图等。 5. 丰富的布局管理...

Global site tag (gtag.js) - Google Analytics