2012-01-28 2 views
8

여기 셀 타일에 노드를 동적으로 추가/제거하는 완전하고 간단한 예제가 있습니다. 내 예제가 잘 작동하지 않습니다. 거기에있는 것 같습니다 새로 고침 문제입니다. 노드를 닫기/확장하는 경우에만 올바른 결과가 표시됩니다. 나는 또한이 문제에 맞는이 포럼에서 어떤 대답도 찾지 못했습니다. 아마도 누군가가 내 사례를 시험해보고 문제가있는 곳을 말해 줄 수 있습니다. 다른 힌트도 매우 환영합니다.GWT - celltree에서 노드 추가 및 제거

인사, 당신의 설명은 마르코

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()); 
    } 
    } 
} 

감사 미트. 닫기 재개 버전을 사용해 보았습니다. 새로 고침 메서드를 다음 메서드로 바꿨습니다. 추가가 작동하지만 제거하지 않습니다. 전체 주제가 매우 이상합니다. 나는이 기본 함수가 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-으로 참여가 권장된다. 문제 다음을 참조하십시오 : http://code.google.com/p/google-web-toolkit/issues/detail?id=7160

현재 상태 : 이 * 추가가 가능하다 * 제거하면되지 마지막 자식 경우에 가능하다!

마지막 열린 지점 인 경우 마지막 열린 지점에서 트리를 새로 고칩니다.

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()); 
      } 
    } 
} 
+0

아무도이 문제를 해결하지 못했습니까? 좌절감이 GWT issuelist에서 설계된대로 닫힙니다 - http://code.google.com/p/google-web-toolkit/issues/detail?id=7160 – SSR

답변

5

이것은 어떻게 든 CellTree의 알려진 문제점입니다.
새로 고침 문제가 발생하는 이유는 getNodeInfo() 함수에서 각 CellTree 수준에 대해 ListDataProvider 인스턴스를 새로 만듭니다.
ListDataProvider의 항목을 업데이트하면 CellTree는 업데이트/새로 고침 만합니다. removeMenu() 및 addSubMenu() 함수는 MyNode 클래스에 저장된 원래 목록에서 항목을 추가 및 제거하지만 해당 ListDataProviders에서 목록을 업데이트하지 않습니다 (디버그 모드에서 확인하려고 시도 할 수 있음).
닫고 다시 할 때 CellTree가 새로 고쳐지는 이유는 노드를 다시 열면 getNodeInfo()이 다시 호출되고 전체 CellTree 구조가 다시 구성되기 때문입니다 (새 메뉴 포함 또는 각각 하나 제거됨).

는 두 가지 해결책이 있습니다

  1. 어딘가에 ListDataProviders 각각에 대한 참조를 유지하고 전화/제거 (그 목록에 추가 내가 항목이 정말 추가 /가 제거되지 않습니다 가정 그렇게하지만,).
  2. 프로그래밍 방식으로 모든 노드를 닫은 다음 다시 엽니 다.

두 가지 모두 피타 구현할 수 있습니다. 불행히도 주변에는 쉬운 방법이 없습니다.

+0

당신의 설명에 감사드립니다. 나는 close-reopen 버전을 시도했다. 추가가 작동하지만 제거하지 않습니다. 제안 된 솔루션 중 하나에 대한 완전한 작동 예제가 있습니까? – user1165474

+0

내일 또는 내일 다음날에 가까운 재개 코드를 게시 할 예정입니다. –

+0

안녕하십니까. 예제가 있습니까? 나는 여전히 그 해결책을 찾지 못했다. – user1165474

0

데이터 공급자에서 유지 관리되는 개체의 배열을 지울뿐입니다. 나는 onRangeChanged(final HasData<?> display)에서 이것을한다.여기에 ListDataProvider을 사용하지 않은 것 같습니다. 대신 AbstractDataProvider<T>을 사용합니다.

노드를 추가하려면 onRangeChanged() 방법으로 목록에 추가 한 다음 updateRowData()으로 전화하십시오. 삭제를 위해이 작업을 수행 할 수도 있습니다.

내가 문제를 핥았 다했다고 생각

0

은 ... 기본적으로 내가 확장 및 CellTree의 많은 부분을 하위 클래스와 거의 완벽한 작업 예를 얻은했습니다. 너무 복잡하여 여기에 문서를 작성하는 것이 아니라 각 노드 내에 데이터 공급자를 저장 한 노드 클래스를 사용하여 솔루션을 작성하는 것으로 충분합니다.

https://code.google.com/p/updatable-cell-tree/

+0

이 링크가 질문에 대답 할 수 있지만 여기에 답변의 핵심 부분을 포함하는 것이 좋습니다 참조 용 링크를 제공하십시오. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않게 될 수 있습니다. – chris

+0

충분히 답답하지만 실제로 답을 보는 데 시간이 걸렸다면 실용적이지는 않습니다. 해결책은 여기에 포함시킬만큼 단순하지 않습니다. – gslender