2012-04-12 3 views
2

Я использовал CellTree, в котором я использовал CompositeCell, содержащий CheckBoxCell на каждом родительском узле, а также на дочернем узле.Как выбрать все дочерние элементы для выбора родительского узла в GWT CellTree?

Теперь я хочу выбрать все дочерние узлы при выборе родительского узла. Как я могу это достичь?

Ниже приведен мой код.

public class CellTreeExample implements EntryPoint { 
    /** 
    * A list of songs. 
    */ 
    private static class Playlist { 
     private final String name; 
     private final List<String> songs = new ArrayList<String>(); 

     public Playlist(String name) { 
      this.name = name; 
     } 

     /** 
     * Add a song to the playlist. 
     * 
     * @param name 
     *   the name of the song 
     */ 
     public void addSong(String name) { 
      songs.add(name); 
     } 

     public String getName() { 
      return name; 
     } 

     /** 
     * Return the list of songs in the playlist. 
     */ 
     public List<String> getSongs() { 
      return songs; 
     } 
    } 

    /** 
    * A composer of classical music. 
    */ 
    private static class Composer { 
     private final String name; 
     private final List<Playlist> playlists = new ArrayList<Playlist>(); 

     public Composer(String name) { 
      this.name = name; 
     } 

     /** 
     * Add a playlist to the composer. 
     * 
     * @param playlist 
     *   the playlist to add 
     */ 
     public Playlist addPlaylist(Playlist playlist) { 
      playlists.add(playlist); 
      return playlist; 
     } 

     public String getName() { 
      return name; 
     } 

     /** 
     * Return the rockin' playlist for this composer. 
     */ 
     public List<Playlist> getPlaylists() { 
      return playlists; 
     } 
    } 

    /** 
    * The model that defines the nodes in the tree. 
    */ 
    private static class CustomTreeModel implements TreeViewModel { 

     private final List<Composer> composers; 

     /** 
     * This selection model is shared across all leaf nodes. A selection 
     * model can also be shared across all nodes in the tree, or each set of 
     * child nodes can have its own instance. This gives you flexibility to 
     * determine how nodes are selected. 
     */ 
     private MultiSelectionModel<String> selectionModel = new MultiSelectionModel<String>(); 
     private MultiSelectionModel<Playlist> playlistSelectionModel = new MultiSelectionModel<Playlist>(); 
     private MultiSelectionModel<Composer> composerSelectionModel = new MultiSelectionModel<Composer>(); 
     private final Cell<String> contactCell; 
     static List<HasCell<String, ?>> hasCells = new ArrayList<HasCell<String, ?>>(); 
     private final Cell<Playlist> playlistCell; 
     static List<HasCell<Playlist, ?>> playlistHasCells = new ArrayList<HasCell<Playlist, ?>>(); 
     private final Cell<Composer> composerCell; 
     static List<HasCell<Composer, ?>> composerHasCells = new ArrayList<HasCell<Composer, ?>>(); 
     public CustomTreeModel(final MultiSelectionModel<String> selectionModel,final MultiSelectionModel<Playlist> playlistSelectionModel,final MultiSelectionModel<Composer> composerSelectionModel) { 
      this.selectionModel = selectionModel; 
      this.playlistSelectionModel = playlistSelectionModel; 
      this.composerSelectionModel = composerSelectionModel; 

      // Create a database of information. 
      composers = new ArrayList<Composer>(); 

      // Add compositions by Beethoven. 
      { 
       Composer beethoven = new Composer("Beethoven"); 
       composers.add(beethoven); 

       Playlist concertos = beethoven.addPlaylist(new Playlist("Concertos")); 
       concertos.addSong("No. 1 - C"); 
       concertos.addSong("No. 2 - B-Flat Major"); 
       concertos.addSong("No. 3 - C Minor"); 
       concertos.addSong("No. 4 - G Major"); 
       concertos.addSong("No. 5 - E-Flat Major"); 

       Playlist quartets = beethoven.addPlaylist(new Playlist("Quartets")); 
       quartets.addSong("Six String Quartets"); 
       quartets.addSong("Three String Quartets"); 
       quartets.addSong("Grosse Fugue for String Quartets"); 

       Playlist sonatas = beethoven.addPlaylist(new Playlist("Sonatas")); 
       sonatas.addSong("Sonata in A Minor"); 
       sonatas.addSong("Sonata in F Major"); 

       Playlist symphonies = beethoven.addPlaylist(new Playlist("Symphonies")); 
       symphonies.addSong("No. 2 - D Major"); 
       symphonies.addSong("No. 2 - D Major"); 
       symphonies.addSong("No. 3 - E-Flat Major"); 
       symphonies.addSong("No. 4 - B-Flat Major"); 
       symphonies.addSong("No. 5 - C Minor"); 
       symphonies.addSong("No. 6 - F Major"); 
       symphonies.addSong("No. 7 - A Major"); 
       symphonies.addSong("No. 8 - F Major"); 
       symphonies.addSong("No. 9 - D Minor"); 
      } 

      // Add compositions by Brahms. 
      { 
       Composer brahms = new Composer("Brahms"); 
       composers.add(brahms); 
       Playlist concertos = brahms.addPlaylist(new Playlist("Concertos")); 
       concertos.addSong("Violin Concerto"); 
       concertos.addSong("Double Concerto - A Minor"); 
       concertos.addSong("Piano Concerto No. 1 - D Minor"); 
       concertos.addSong("Piano Concerto No. 2 - B-Flat Major"); 

       Playlist quartets = brahms.addPlaylist(new Playlist("Quartets")); 
       quartets.addSong("Piano Quartet No. 1 - G Minor"); 
       quartets.addSong("Piano Quartet No. 2 - A Major"); 
       quartets.addSong("Piano Quartet No. 3 - C Minor"); 
       quartets.addSong("String Quartet No. 3 - B-Flat Minor"); 

       Playlist sonatas = brahms.addPlaylist(new Playlist("Sonatas")); 
       sonatas.addSong("Two Sonatas for Clarinet - F Minor"); 
       sonatas.addSong("Two Sonatas for Clarinet - E-Flat Major"); 

       Playlist symphonies = brahms.addPlaylist(new Playlist("Symphonies")); 
       symphonies.addSong("No. 1 - C Minor"); 
       symphonies.addSong("No. 2 - D Minor"); 
       symphonies.addSong("No. 3 - F Major"); 
       symphonies.addSong("No. 4 - E Minor"); 
      } 

      // Add compositions by Mozart. 
      { 
       Composer mozart = new Composer("Mozart"); 
       composers.add(mozart); 
       Playlist concertos = mozart.addPlaylist(new Playlist("Concertos")); 
       concertos.addSong("Piano Concerto No. 12"); 
       concertos.addSong("Piano Concerto No. 17"); 
       concertos.addSong("Clarinet Concerto"); 
       concertos.addSong("Violin Concerto No. 5"); 
       concertos.addSong("Violin Concerto No. 4"); 
      } 

      hasCells.add(new HasCell<String, Boolean>() { 

       private CheckboxCell cell = new CheckboxCell(true, false){ 

       /* (non-Javadoc) 
       * @see com.google.gwt.cell.client.CheckboxCell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Boolean, com.google.gwt.safehtml.shared.SafeHtmlBuilder) 
       */ 
       @Override 
       public void render(Context context, Boolean value, SafeHtmlBuilder sb) { 
        // TODO Auto-generated method stub 
        super.render(context, value, sb); 
       } 

       }; 

       public Cell<Boolean> getCell() { 
       return cell; 
       } 

       public FieldUpdater<String, Boolean> getFieldUpdater() { 
       return null; 
       } 

       public Boolean getValue(String object) { 
       return selectionModel.isSelected(object); 
       } 
      }); 


      contactCell = new CompositeCell<String>(hasCells){ 
       /* @Override 
       public void render(Context context, String value, SafeHtmlBuilder sb) { 
        System.out.println("STRING...."+value+" ...."); 
        //sb.appendHtmlConstant("<table><tbody><tr>"); 
        sb.appendHtmlConstant(value); 
        super.render(context, value, sb); 
        //sb.appendHtmlConstant(value+"</tr></tbody></table>"); 
       }*/ 

       @Override 
       protected Element getContainerElement(Element parent) { 
        // Return the first TR element in the table. 
        return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement(); 
       } 

       @Override 
       protected <X> void render(Context context, String value, 
        SafeHtmlBuilder sb, HasCell<String, X> hasCell) { 
        Cell<X> cell = hasCell.getCell(); 
        cell.render(context, hasCell.getValue(value), sb); 
        sb.appendHtmlConstant(value); 
        //sb.appendHtmlConstant("</td>"); 
       } 
      }; 

      playlistHasCells.add(new HasCell<Playlist, Boolean>() { 

        private CheckboxCell cell = new CheckboxCell(true, false){ 

        /* (non-Javadoc) 
        * @see com.google.gwt.cell.client.CheckboxCell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Boolean, com.google.gwt.safehtml.shared.SafeHtmlBuilder) 
        */ 
        @Override 
        public void render(Context context, Boolean value, SafeHtmlBuilder sb) { 
         // TODO Auto-generated method stub 
         super.render(context, value, sb); 
        } 

        }; 

        public Cell<Boolean> getCell() { 
        return cell; 
        } 

        public FieldUpdater<Playlist, Boolean> getFieldUpdater() { 
        return null; 
        } 

        public Boolean getValue(Playlist object) { 
        return playlistSelectionModel.isSelected(object); 
        } 
       }); 
      playlistCell = new CompositeCell<Playlist>(playlistHasCells){ 
           @Override 
       protected Element getContainerElement(Element parent) { 
        // Return the first TR element in the table. 
        return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement(); 
       } 

       @Override 
       protected <X> void render(Context context, Playlist value, 
        SafeHtmlBuilder sb, HasCell<Playlist, X> hasCell) { 
        Cell<X> cell = hasCell.getCell(); 
        cell.render(context, hasCell.getValue(value), sb); 
        sb.appendHtmlConstant(value.getName()); 
        //sb.appendHtmlConstant("</td>"); 
       } 
      }; 

      composerHasCells.add(new HasCell<Composer, Boolean>() { 

        private CheckboxCell cell = new CheckboxCell(true, false){ 

        /* (non-Javadoc) 
        * @see com.google.gwt.cell.client.CheckboxCell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Boolean, com.google.gwt.safehtml.shared.SafeHtmlBuilder) 
        */ 
        @Override 
        public void render(Context context, Boolean value, SafeHtmlBuilder sb) { 
         // TODO Auto-generated method stub 
         super.render(context, value, sb); 
        } 

        }; 

        public Cell<Boolean> getCell() { 
        return cell; 
        } 

        public FieldUpdater<Composer, Boolean> getFieldUpdater() { 
        return null; 
        } 

        public Boolean getValue(Composer object) { 
        return composerSelectionModel.isSelected(object); 
        } 
       }); 
      composerCell = new CompositeCell<Composer>(composerHasCells){ 
           @Override 
       protected Element getContainerElement(Element parent) { 
        // Return the first TR element in the table. 
        return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement(); 
       } 

       @Override 
       protected <X> void render(Context context, Composer value, 
        SafeHtmlBuilder sb, HasCell<Composer, X> hasCell) { 
        Cell<X> cell = hasCell.getCell(); 
        cell.render(context, hasCell.getValue(value), sb); 
        sb.appendHtmlConstant(value.getName()); 
        //sb.appendHtmlConstant("</td>"); 
       } 
      }; 
     } 



     /** 
     * Get the {@link NodeInfo} that provides the children of the specified 
     * value. 
     */ 
     public <T> NodeInfo<?> getNodeInfo(T value) { 
      if (value == null) { 
       // LEVEL 0. 
       // We passed null as the root value. Return the composers. 

       // Create a data provider that contains the list of composers. 
       ListDataProvider<Composer> dataProvider = new ListDataProvider<CellTreeExample.Composer>(composers); 

       // Create a cell to display a composer. 
       Cell<Composer> cell = new AbstractCell<Composer>() { 
        @Override 
        public void render(Context context, Composer value, SafeHtmlBuilder sb) { 
         if (value != null) { 
          sb.appendEscaped(value.getName()); 
         } 
        } 
       }; 

       // Return a node info that pairs the data provider and the cell. 
       return new DefaultNodeInfo<Composer>(dataProvider, composerCell); 
      } else if (value instanceof Composer) { 
       // LEVEL 1. 
       // We want the children of the composer. Return the playlists. 
       ListDataProvider<Playlist> dataProvider = new ListDataProvider<Playlist>(((Composer) value) 
         .getPlaylists()); 
       Cell<Playlist> cell = new AbstractCell<Playlist>() { 
        @Override 
        public void render(Context context, Playlist value, SafeHtmlBuilder sb) { 
         if (value != null) { 
          sb.appendEscaped(value.getName()); 
         } 
        } 
       }; 
       return new DefaultNodeInfo<Playlist>(dataProvider, playlistCell); 
      } else if (value instanceof Playlist) { 
       // LEVEL 2 - LEAF. 
       // We want the children of the playlist. Return the songs. 

       ListDataProvider<String> dataProvider = new ListDataProvider<String>(((Playlist) value).getSongs()); 
       /*CellList<String> cellList = new CellList<String>(contactCell); 
       dataProvider.addDataDisplay(cellList);*/ 
       // Use the shared selection model. 
       return new DefaultNodeInfo<String>(dataProvider, contactCell, selectionModel, null); 
      } 

      return null; 
     } 

     /** 
     * Check if the specified value represents a leaf node. Leaf nodes 
     * cannot be opened. 
     */ 
     public boolean isLeaf(Object value) { 
      // The leaf nodes are the songs, which are Strings. 
      if (value instanceof String) { 
       return true; 
      } 
      return false; 
     } 
    } 

    public void onModuleLoad() { 
     final MultiSelectionModel<String> selectionModel = 
       new MultiSelectionModel<String>(); 
     final MultiSelectionModel<Playlist> playlistSelectionModel = 
       new MultiSelectionModel<Playlist>(); 
     final MultiSelectionModel<Composer> composerSelectionModel = 
       new MultiSelectionModel<Composer>(); 
     // Create a model for the tree. 
     TreeViewModel model = new CustomTreeModel(selectionModel,playlistSelectionModel,composerSelectionModel); 

     /* 
     * Create the tree using the model. We use <code>null</code> as the 
     * default value of the root node. The default value will be passed to 
     * CustomTreeModel#getNodeInfo(); 
     */ 
     CellTree tree = new CellTree(model, null); 

     tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED); 

     // Open the first playlist by default. 
     TreeNode rootNode = tree.getRootTreeNode(); 
     TreeNode firstPlaylist = rootNode.setChildOpen(0, true); 
     firstPlaylist.setChildOpen(0, true); 

     // Add the tree to the root layout panel. 
     RootLayoutPanel.get().add(tree); 
    } 
} 

Мой код обработчика здесь:

playlistSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { 

      @Override 
      public void onSelectionChange(SelectionChangeEvent event) { 
       Set<Playlist> playlistSet = playlistSelectionModel.getSelectedSet(); 
       Iterator<Playlist> itr = playlistSet.iterator(); 
       while (itr.hasNext()) { 
        Playlist selectedPlaylist = itr.next(); 
        System.out.println("sel: " + selectedPlaylist.getName()); 
        if (selectedPlaylist != null){ 
         for (String song : selectedPlaylist.getSongs()) { 
          selectionModel.setSelected(song, true); 
         } 
        } 
       } 

      } 
     }); 

     composerSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { 

      @Override 
      public void onSelectionChange(SelectionChangeEvent event) { 
       Set<Composer> composerSet = composerSelectionModel.getSelectedSet(); 
       Iterator<Composer> itr = composerSet.iterator(); 
       while (itr.hasNext()) { 
        Composer selectedComposer = itr.next(); 
        if (selectedComposer != null) { 
         for (Playlist playlist : selectedComposer.getPlaylists()) { 
          playlistSelectionModel.setSelected(playlist, true); 
         } 
        } 
       } 
      } 
     }); 
    } 

ответ

2

Вам нужно два SelectionModel с.
Добавьте SelectionChangeHandler в SelectionModel ваших родительских узлов, а в обработчике загрузите все дочерние объекты для родительского объекта и вызовите на них MultiSelectionModel.setSelected(Obj,true).

Нечто подобное для списка воспроизведения и песни:

Update: на основе комментариев:

playListSelectionModel.addSelectionChangerHandler(new SelectionChangeEvent.Handler(SelectionChangeEvent event) { 
    ArrayList<PlayList> playLists; // all playlists 
    for (PlayList playlist:playlists) { 
     boolean isSelected = playlistSelectionModel.isSelected(playlist); 
     for (String song : selectedPlaylist.getSongs()) { 
      selectionModel.setSelected(song, isSelected); 
     } 
    } 
}}; 

Это работает, когда playListSelectionModel является SingleSelectionModel. В случае, если это MultiSelectionModel, вам понадобятся две петли.

+0

Спасибо Umit, но всякий раз, когда я проверяю/снимаю флажок, я получаю исключение: 11: 00: 05.112 [ERROR] [celltreeexample] Неиспользуемое исключение escaped com.google.gwt.core.client.JavaScriptException: (TypeError) : 'firstChild' является нулевым или нет объектом в com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript (BrowserChannelServer.java:248) – Madhura

+0

привет, я избавился от этой ошибки, но теперь ничего не происходит даже после того, как я выбираю или снимите флажок :-( – Madhura

+0

Думаю, вам нужно добавить реализацию ProvidesKey для вашей песни и PlayList DTO. См. [здесь] (http://code.google.com/p/google-web-toolkit/source/browse/ trunk/user/javadoc/com/google/gwt/examples/view/KeyProviderExample.java? r = 8944) для получения дополнительной информации. –

Смежные вопросы