gpt4 book ai didi

GWT - 在 celltree 中添加和删除节点

转载 作者:行者123 更新时间:2023-12-04 08:28:24 24 4
gpt4 key购买 nike

在这里,我有一个完整且非常简单的示例来动态添加/删除
单元格树的节点。我的例子效果不佳。好像有
是刷新问题。只有关闭/展开节点才会显示正确的
结果。我也没有在这个论坛中找到任何适合这个问题的答案。
也许有人可以试试我的例子并告诉我问题出在哪里。
任何其他提示也非常感谢。

问候, 马可

import java.util.ArrayList;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;

public class MyCelltreeTest implements EntryPoint {
private AbsolutePanel absolutePanel;
private CellTree cellTree;
private Button btnAdd;
private Button btnRemove;
private MyTreeModel myTreeModel;
private SingleSelectionModel<MyNode> selectionModelCellTree = null;

@Override
public void onModuleLoad() {
RootPanel rootPanel = RootPanel.get();
rootPanel.add(getAbsolutePanel(), 0, 0);
}

private AbsolutePanel getAbsolutePanel() {
if (absolutePanel == null) {
absolutePanel = new AbsolutePanel();
absolutePanel.setSize("612px", "482px");
absolutePanel.add(getCellTree(), 0, 0);
absolutePanel.add(getBtnAdd(), 265, 428);
absolutePanel.add(getBtnRemove(), 336, 428);
}
return absolutePanel;
}

private CellTree getCellTree() {
if (cellTree == null) {
myTreeModel = new MyTreeModel();
cellTree = new CellTree(myTreeModel, null);
cellTree.setSize("285px", "401px");
}
return cellTree;
}

private Button getBtnAdd() {
if (btnAdd == null) {
btnAdd = new Button("Add");
btnAdd.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {

MyNode node = selectionModelCellTree.getSelectedObject();
if(node != null)
myTreeModel.addNew(node, "Bla");
}
});
}
return btnAdd;
}

private Button getBtnRemove() {
if (btnRemove == null) {
btnRemove = new Button("Remove");
btnRemove.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
MyNode node = selectionModelCellTree.getSelectedObject();
if(node != null)
myTreeModel.remove(node);
}
});
}
return btnRemove;
}

public class MyNode {
private String name;
private ArrayList<MyNode> childs; //nodes childrens
private MyNode parent; //track internal parent
private MyCell cell; //for refresh - reference to visual component

public MyNode(String name) {
super();
parent = null;
this.name = name;
childs = new ArrayList<MyNode>();
}

public void addSubMenu(MyNode m) {
m.parent = this;
childs.add(m);
}

public void removeMenu(MyNode m) {

m.getParent().childs.remove(m);
}

public boolean hasChildrens() {
return childs.size()>0;
}

public ArrayList<MyNode> getList() {
return childs;
}

public MyNode getParent() {
return parent;
}

public void setCell(MyCell cell) {
this.cell = cell;
}

public void refresh() {
if(parent!=null) {
parent.refresh();
}
if (cell!=null) {
cell.refresh(); //refresh tree
}
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

public class MyTreeModel implements TreeViewModel {
private MyNode officialRoot; //default not dynamic
private MyNode studentRoot; //default not dynamic
private MyNode testRoot; //default not dynamic
private MyNode root;

public MyNode getRoot() { // to set CellTree root
return root;
}

public MyTreeModel() {
selectionModelCellTree = new SingleSelectionModel<MyNode>();
root = new MyNode("root");
// Default items
officialRoot = new MyNode("Cat"); //some basic static data
studentRoot = new MyNode("Dog");
testRoot = new MyNode("Fish");
root.addSubMenu(officialRoot);
root.addSubMenu(studentRoot);
root.addSubMenu(testRoot);
}

//example of add add logic
public void addNew(MyNode myparent, String name) {
myparent.addSubMenu(new MyNode(name));
myparent.refresh(); //HERE refresh tree
}
public void remove(MyNode objToRemove) {

objToRemove.removeMenu(objToRemove);
objToRemove.refresh();
}

@Override
public <T> NodeInfo<?> getNodeInfo(T value) {
ListDataProvider<MyNode> dataProvider;
MyNode myValue = null;
if (value == null) { // root is not set
dataProvider = new ListDataProvider<MyNode>(root.getList());
} else {
myValue = (MyNode) value;
dataProvider = new ListDataProvider<MyNode>(myValue.getList());
}
MyCell cell = new MyCell(dataProvider); //HERE Add reference
if (myValue != null)
myValue.setCell(cell);
return new DefaultNodeInfo<MyNode>(dataProvider, cell, selectionModelCellTree, null);
}

@Override
public boolean isLeaf(Object value) {
if (value instanceof MyNode) {
MyNode t = (MyNode) value;
if (!t.hasChildrens())
return true;
return false;
}
return false;
}
}

public class MyCell extends AbstractCell<MyNode> {
ListDataProvider<MyNode> dataProvider; //for refresh

public MyCell(ListDataProvider<MyNode> dataProvider) {
super();
this.dataProvider = dataProvider;
}
public void refresh() {
dataProvider.refresh();
}

@Override
public void render(Context context, MyNode value, SafeHtmlBuilder sb) {
if (value == null) {
return;
}
sb.appendEscaped(value.getName());
}
}
}

感谢 Ümit 的解释。
我尝试了关闭重新打开版本。
我已经用下面的方法替换了我的刷新方法。
添加有效,但删除无效。
整个话题很奇怪。我很惊讶这些基本的
GWT 并不真正支持函数。
有人可以给我更多帮助来运行一个真正的工作示例。
    public void refresh() {

closeReopenTreeNodes(cellTree.getRootTreeNode());
}

private void closeReopenTreeNodes(TreeNode node) {
if(node == null) {
return;
}
for(int i = 0; i < node.getChildCount(); i++) {

if(node.getChildValue(i).equals(this)){

if(node.getParent() != null){

node.getParent().setChildOpen(i, false);
//node.getParent().setChildOpen(i, true);
}

node.setChildOpen(i, false);
node.setChildOpen(i, true);
}
TreeNode child = node.setChildOpen(i, node.isChildOpen(i));
closeReopenTreeNodes(child);
}
}

这是我的第三次尝试:
这种方式是 gwt-commiter 推荐的。
请看以下问题:
http://code.google.com/p/google-web-toolkit/issues/detail?id=7160

当前状态:
* 添加是可能的
* 如果不是最后一个 child ,删除是可能的!

所以,最后一个打开点,如果最后一个打开的 child 刷新树!
package com.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;

public class MyCelltreeTest2 implements EntryPoint {
private AbsolutePanel absolutePanel;
private CellTree cellTree;
private Button btnAdd;
private Button btnRemove;
private MyTreeModel myTreeModel;
private SingleSelectionModel<MyNode> selectionModelCellTree = null;
private Map<MyNode, ListDataProvider<MyNode>> mapDataProviders = null;
private ListDataProvider<MyNode> rootDataProvider = null;

public void onModuleLoad() {
RootPanel rootPanel = RootPanel.get();
rootPanel.add(getAbsolutePanel(), 0, 0);
}

private AbsolutePanel getAbsolutePanel() {
if (absolutePanel == null) {
absolutePanel = new AbsolutePanel();
absolutePanel.setSize("612px", "482px");
absolutePanel.add(getCellTree(), 0, 0);
absolutePanel.add(getBtnAdd(), 265, 428);
absolutePanel.add(getBtnRemove(), 336, 428);
}
return absolutePanel;
}
private CellTree getCellTree() {
if (cellTree == null) {
myTreeModel = new MyTreeModel();
cellTree = new CellTree(myTreeModel, null);
cellTree.setSize("285px", "401px");
}
return cellTree;
}
private Button getBtnAdd() {
if (btnAdd == null) {
btnAdd = new Button("Add");
btnAdd.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {

MyNode node = selectionModelCellTree.getSelectedObject();

myTreeModel.add(node, "Bla");
}
});
}
return btnAdd;
}
private Button getBtnRemove() {
if (btnRemove == null) {
btnRemove = new Button("Remove");
btnRemove.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {

MyNode node = selectionModelCellTree.getSelectedObject();

myTreeModel.remove(node);
}
});
}
return btnRemove;
}


public class MyNode {

private String name;
private ArrayList<MyNode> childs; //nodes childrens
private MyNode parent; //track internal parent


public MyNode(String name) {
super();
parent = null;
this.name = name;
childs = new ArrayList<MyNode>();
}
public boolean hasChildrens() {
return childs.size()>0;
}
public ArrayList<MyNode> getList() {
return childs;
}
public MyNode getParent() {
return parent;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

public class MyTreeModel implements TreeViewModel {


public MyTreeModel() {
selectionModelCellTree = new SingleSelectionModel<MyNode>();
mapDataProviders = new HashMap<MyCelltreeTest2.MyNode, ListDataProvider<MyNode>>();
}

public void add(MyNode myparent, String name) {

MyNode child = new MyNode(name);

//root-node
if(myparent == null){
rootDataProvider.getList().add(child);
mapDataProviders.put(child, rootDataProvider);
}
else{

ListDataProvider<MyNode> dataprovider = mapDataProviders.get(myparent);
myparent.childs.add(child);
child.parent = myparent;
dataprovider.refresh();
}
}
public void remove(MyNode objToRemove) {

ListDataProvider<MyNode> dataprovider = mapDataProviders.get(objToRemove);
dataprovider.getList().remove(objToRemove);
// mapDataProviders.remove(objToRemove);
dataprovider.refresh();
dataprovider.flush();

if(objToRemove.parent != null){
ListDataProvider<MyNode> dataproviderParent = mapDataProviders.get(objToRemove.parent);
objToRemove.parent.childs.remove(objToRemove);
dataproviderParent.refresh();
dataproviderParent.flush();
}
else{
rootDataProvider.refresh();
rootDataProvider.flush();
}
}


@Override
public <T> NodeInfo<?> getNodeInfo(T value) {

if (value == null) { // root is not set
rootDataProvider = new ListDataProvider<MyNode>(new ArrayList<MyNode>());
MyCell cell = new MyCell();
return new DefaultNodeInfo<MyNode>(rootDataProvider, cell,
selectionModelCellTree, null);
} else {
MyNode myValue = (MyNode) value;
ListDataProvider<MyNode> dataProvider =
new ListDataProvider<MyNode>(myValue.childs);
MyCell cell = new MyCell();
for(MyNode currentNode : myValue.childs){
mapDataProviders.put(currentNode, dataProvider);
}
return new DefaultNodeInfo<MyNode>(dataProvider, cell,
selectionModelCellTree, null);
}
}

@Override
public boolean isLeaf(Object value) {
if (value instanceof MyNode) {
MyNode t = (MyNode) value;
if (!t.hasChildrens())
return true;
return false;
}
return false;
}

}

public class MyCell extends AbstractCell<MyNode> {
public MyCell() {
super();
}
@Override
public void render(Context context, MyNode value, SafeHtmlBuilder sb) {
if (value == null) {
return;
}
sb.appendEscaped(value.getName());
}
}
}

最佳答案

这在某种程度上是 CellTree 的一个已知问题。
刷新问题的原因是在getNodeInfo()函数你新建ListDataProvider每个 CellTree 级别的实例。
如果您更新 ListDataProvider 中的项目,CellTree 只会更新/刷新自身。 .
我相信您的 removeMenu() 和 addSubMenu() 函数从存储在 MyNode 类中的原始列表中添加和删除项目,但不会更新相应 ListDataProviders 中的列表(您可以尝试在 Debug模式下检查)。
关闭再重新刷新CellTree的原因
-打开节点是因为当您重新打开节点时getNodeInfo()被再次调用,整个 CellTree 结构将被再次构造(分别包括新菜单或不包括删除的菜单)。

有两种可能的解决方案:

  • 保留每个 ListDataProviders 的引用某处并在该列表上调用 remove/add (尽管您这样做了,但我认为这些项目并未真正在那里添加/删除)。
  • 以编程方式关闭所有节点并重新打开它。

  • 两者都是要实现的 PITA。不幸的是,没有简单的方法可以解决它。

    关于GWT - 在 celltree 中添加和删除节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9044688/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com