`
java_doc
  • 浏览: 19631 次
  • 性别: 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都找不到文件,要在哪里注册吗 怎么注册啊?


谢谢啊~~~~

相关推荐

Global site tag (gtag.js) - Google Analytics