2012-01-28 8 views
8

यहाँ में नोड्स को दूर मैं गतिशील/जोड़ने एक celltree को नोड्स को हटाने के लिए एक पूर्ण और बहुत ही आसान उदाहरण है। मेरा उदाहरण बहुत अच्छी तरह से काम नहीं कर रहा है। ऐसा लगता है कि एक ताज़ा समस्या है। केवल नोड्स को बंद/विस्तार करने से सही परिणाम दिखाई देगा। मुझे इस मंच में कोई जवाब नहीं मिला जो इस समस्या से जुड़ा हुआ है। शायद कोई मेरा उदाहरण आज़मा सकता है और मुझे बता सकता है कि समस्या कहां है। कोई अन्य संकेत भी बहुत सराहना की है।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()); 
    } 
    } 
} 

धन्यवाद Ümit अपने विवरण के लिए। मैंने क्लोज-रीपेन संस्करण की कोशिश की। मैंने अपनी रीफ्रेश विधि को नीचे दी गई विधियों के साथ बदल दिया है। जोड़ना काम कर रहा है लेकिन नहीं हटा रहा है। पूरे विषय में बहुत अजीब है। मुझे बहुत आश्चर्य है कि ये मूल फ़ंक्शंस वास्तव में जीडब्ल्यूटी द्वारा समर्थित नहीं हैं। क्या कोई मुझे वास्तविक कामकाजी उदाहरण चलाने के लिए और अधिक सहायता दे सकता है।

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

वर्तमान स्थिति: * जोड़ना संभव है * निकाला जा रहा है नहीं तो अंतिम संतान संभव है!

तो, पिछले खुले बिंदु, पेड़ अगर खोले गए अंतिम बच्चे को ताज़ा!

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

क्या किसी ने इसे इस तरीके से अपना रास्ता प्राप्त कर लिया है? निराशाजनक रूप से यह बंद है क्योंकि जीडब्ल्यूटी जारीकर्ता - - http://code.google.com/p/google-web-toolkit/issues/detail?id=7160 – SSR

उत्तर

5

यह किसी भी तरह से सेलट्री के साथ एक ज्ञात समस्या है।
ताज़ा समस्या के लिए कारण यह है कि getNodeInfo() समारोह में आप प्रत्येक CellTree स्तर के लिए एक नया ListDataProvider उदाहरण पैदा करते हैं।
यदि आप ListDataProvider में आइटम अपडेट करते हैं तो सेलट्री केवल अपडेट/रीफ्रेश हो जाती है। मुझे लगता है कि अपने removeMenu() और addSubMenu() फ़ंक्शन जोड़ सकते हैं और अपने MyNode वर्ग में संग्रहीत मूल सूची से आइटम निकालने लेकिन (आप यह देखना होगा कि डिबग मोड में कोशिश कर सकते हैं) इसी ListDataProviders में सूची अपडेट नहीं होगा विश्वास करते हैं।
जब आप बंद करते हैं और को खोलते हैं तो सेलट्री को रीफ्रेश किया जाता है - नोड्स खोलें क्योंकि जब आप नोड्स को फिर से खोलते हैं तो getNodeInfo() को फिर से कॉल किया जाता है और संपूर्ण सेलट्री संरचना फिर से बनाई जाएगी (नए मेनू सहित या बिना क्रमशः एक हटा दिया)।

दो संभव समाधान कर रहे हैं:

  1. कहीं ListDataProviders से प्रत्येक के लिए एक संदर्भ रखें और फोन हटाने/उस सूची में जोड़ (हालांकि आपको लगता है कि मुझे लगता है कि आइटम वास्तव में नहीं जोड़ा जाता है/वहाँ से हटाया करना)।
  2. प्रोग्रामिंग रूप से सभी नोड्स बंद करें और इसे फिर से खोलें।

दोनों किसी भी तरह लागू करने के लिए एक PITA हैं। दुर्भाग्य से इसके चारों ओर कोई आसान तरीका नहीं है।

+0

धन्यवाद आपके स्पष्टीकरण के लिए धन्यवाद। मैंने क्लोज-रीपेन संस्करण की कोशिश की। जोड़ना काम कर रहा है लेकिन नहीं हटा रहा है। क्या आपके पास सुझाए गए समाधानों में से एक के लिए एक पूर्ण कार्य उदाहरण है? – user1165474

+0

मैं के बाद कल –

+0

हाय Ümit एक करीबी फिर से खोलना कोड कल या वें दिन पोस्ट करेंगे, आपको एक उदाहरण है? मुझे अभी भी इसके लिए कोई समाधान नहीं मिला है। – user1165474

0

मैं बस अपना डेटा प्रदाता में बनाए रखा ऑब्जेक्ट की श्रेणी को साफ़ करें। मैं इसे onRangeChanged(final HasData<?> display) में करता हूं।मुझे लगता है कि मैं यहाँ एक ListDataProvider का उपयोग नहीं करते, मैं कुछ बजाय AbstractDataProvider<T> विस्तार का उपयोग करें।

नोड जोड़ने के लिए इसे onRangeChanged() विधि में अपनी सूची में जोड़ें और फिर updateRowData() पर कॉल करें। आप इसे हटाने के लिए भी कर सकते हैं।

0

मुझे लगता है कि मैं इस समस्या पाला हो सकता है ...

अनिवार्य रूप से मैं बढ़ाया और CellTree के कई हिस्सों उपवर्गों और एक लगभग पूर्ण काम कर उदाहरण प्राप्त किया है किया है। यहां दस्तावेज़ करने के लिए बहुत जटिल है, लेकिन एक नोड क्लास का उपयोग करके शामिल समाधान कहने के लिए पर्याप्त है जहां मैंने प्रत्येक नोड के भीतर डेटा प्रदाता को संग्रहीत किया था।

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

+0

(शायद भी GWT खुद के लिए एक पैच प्रदान), यह जवाब के आवश्यक हिस्से को यहां शामिल करने के लिए बेहतर है लागू करने के लिए '' CellTree'' वर्ग का विस्तार करने की है और संदर्भ के लिए लिंक प्रदान करते हैं। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। – chris

+0

पर्याप्त मेले, लेकिन वास्तव में व्यावहारिक नहीं है, तो आप समय वास्तव में इस सवाल का जवाब को देखने के लिए ले लिया। समाधान यहाँ शामिल करने के लिए पर्याप्त कुछ आसान नहीं है हाँ? – gslender