How to report that the GWT cell widget data has been changed via Event Bus?

I have a GWT cell tree that I use to display the file structure from CMS. I am using AsyncDataProvider , which loads data from a custom RPC class that I created. I also have a Web Socket system that will broadcast events (create, rename, move, delete, etc.) from other clients also working on the system.

What I'm trying to circle around me is when I receive one of these events, how do I correctly update my cell tree?

I believe that this problem would be similar to the fact that I had two instances of my cell tree on the page that represent the same data on the server side and want to make sure that when the user updates them and the other updates through using EventBus .

I feel it should be pretty simple, but I spent about 6 hours without it. My code is below:

NOTE. I do not use RequestFactory, although it may look like it is my custom RPC environment. In addition, FileEntity is simply a representation of a file having a name accessible by getName() .

 private void drawTree() { // fileService is injected earlier on and is my own custom rpc service TreeViewModel model = new CustomTreeModel(new FileDataProvider(fileService)); CellTree tree = new CellTree(model, "Root"); tree.setAnimationEnabled(true); getView().getWorkspace().add(tree); } private static class CustomTreeModel implements TreeViewModel { // I am trying to use a single AsyncDataProvider so I have a single point of loading data which I can manipulate (Not sure if this is the correct way to go) public CustomTreeModel(FileDataProvider dataProvider) { this.provider = provider; } public <T> NodeInfo<?> getNodeInfo(final T value) { if (!(value instanceof FileEntity)) { // I already have the root File loaded in my presenter, if we are at the root of the tree, I just add it via a list here ListDataProvider<FileEntity> dataProvider = new ListDataProvider<FileEntity>(); dataProvider.getList().add(TreeWorkspacePresenter.rootFolder); return new DefaultNodeInfo<FileEntity>(dataProvider, new FileCell()); } else { // Otherwise I know that we are loading some tree child data, and I invoke the AsyncProvider to load it from the server provider.setFocusFile(value); return new DefaultNodeInfo<FileEntity>(provider, new FileCell()); } } public boolean isLeaf(Object value) { if(value == null || value instanceof Folder) return false; return true; } } public class FileDataProvider extends AsyncDataProvider<FileEntity> { private FileEntity focusFile; private FileService service; @Inject public FileDataProvider(FileService service){ this.service = service; } public void setFocusFile(FileEntity focusFile){ this.focusFile = focusFile; } @Override protected void onRangeChanged(HasData<FileEntity> display) { service.getChildren(((Folder) focusFile), new Reciever<List<FileEntity>>() { @Override public void onSuccess(List<FileEntity> files) { updateRowData(0, files); } @Override public void onFailure(Throwable error) { Window.alert(error.toString()); } }); } } /** * The cell used to render Files. */ public static class FileCell extends AbstractCell<FileEntity> { private FileEntity file; public FileEntity getFile() { return file; } @Override public void render(Context context, FileEntity file, SafeHtmlBuilder sb) { if (file != null) { this.file = file; sb.appendEscaped(file.getName()); } } } 
+6
source share
2 answers

There is currently no direct support for updating individual tree elements even in the latest version of gwt.

But there is a workaround for this. Each element of the tree is associated with a value. Using this value, you can get the corresponding tree element.

In your case, I assume you know which item to update / update, i.e. you know which file entity has changed. Use this file to find the corresponding tree item. Once you get the tree element, you just need to expand, collapse or collapse and expand your parent element. This allows the parent to re-display its children. Your modified file object is one of them. So it is updated.

 public void refreshFileEntity(FileEntity fileEntity) { TreeNode fileEntityNode = getFileEntityNode(fileEntity, cellTree.getRootTreeNode() // For expnad and collapse run this for loop for ( int i = 0; i < fileEntityNode.getParent().getChildCount(); i++ ) { if ( !fileEntityNode.getParent().isChildLeaf( i ) ) { fileEntityNode.getParent().setChildOpen( i, true ); } } } public TreeNode getFileEntityNode(FileEntity fileEntity, TreeNode treeNode) { if(treeNode.getChildren == null) { return null; } for(TreeNode node : treeNode.getChildren()) { if(fileEntity.getId().equals( node.getValue.getId() )) { return node; } getEntityNode(fileEntity, node); } } 
+2
source

You can use dataprovider to update celltree. You can update the complete cell tree:

 provider.setList(pList); provider.refresh(); 

If you want to update only a special cell, you can get a listwrapper from a dataparauder and set only one item.

 provider.getList().set(12, element); 
0
source

All Articles