2

CellTree在其中使用了CompositeCell包含CheckBoxCell在每个父节点和子节点上的内容。

现在我想在选择父节点时选择所有子节点。我怎样才能做到这一点?

以下是我的代码。

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

1 回答 1

2

你需要两个SelectionModels。
将 a 添加SelectionChangeHandlerSelectionModel您的父节点并在处理程序中检索父对象的所有子对象并在它们上调用MultiSelectionModel.setSelected(Obj,true)

播放列表和歌曲是这样的:

更新:基于评论:

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你需要两个循环。

于 2012-04-12T20:55:12.637 回答